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

« back to all changes in this revision

Viewing changes to contrib/ICSharpCode.NRefactory.CSharp/Parser/mcs/location.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
 
// location.cs: Keeps track of the location of source code entity
3
 
//
4
 
// Author:
5
 
//   Miguel de Icaza
6
 
//   Atsushi Enomoto  <atsushi@ximian.com>
7
 
//   Marek Safar (marek.safar@gmail.com)
8
 
//
9
 
// Copyright 2001 Ximian, Inc.
10
 
// Copyright 2005 Novell, Inc.
11
 
//
12
 
 
13
 
using System;
14
 
using System.Collections.Generic;
15
 
using Mono.CompilerServices.SymbolWriter;
16
 
using System.Diagnostics;
17
 
using System.Linq;
18
 
 
19
 
namespace Mono.CSharp
20
 
{
21
 
        //
22
 
        //  This is one single source file.
23
 
        //
24
 
        public class SourceFile : IEquatable<SourceFile>
25
 
        {
26
 
                //
27
 
                // Used by #line directive to track hidden sequence point
28
 
                // regions
29
 
                //
30
 
                struct LocationRegion : IComparable<LocationRegion>
31
 
                {
32
 
                        public readonly Location Start;
33
 
                        public readonly Location End;
34
 
 
35
 
                        public LocationRegion (Location start, Location end)
36
 
                        {
37
 
                                this.Start = start;
38
 
                                this.End = end;
39
 
                        }
40
 
 
41
 
                        public int CompareTo (LocationRegion other)
42
 
                        {
43
 
                                if (Start.Row == other.Start.Row)
44
 
                                        return Start.Column.CompareTo (other.Start.Column);
45
 
 
46
 
                                return Start.Row.CompareTo (other.Start.Row);
47
 
                        }
48
 
 
49
 
                        public override string ToString ()
50
 
                        {
51
 
                                return Start.ToString () + " - " + End.ToString ();
52
 
                        }
53
 
                }
54
 
 
55
 
                public readonly string Name;
56
 
                public readonly string FullPathName;
57
 
                public readonly int Index;
58
 
                public bool AutoGenerated;
59
 
 
60
 
                SourceFileEntry file;
61
 
                byte[] guid, checksum;
62
 
                List<LocationRegion> hidden_lines;
63
 
 
64
 
                public SourceFile (string name, string path, int index)
65
 
                {
66
 
                        this.Index = index;
67
 
                        this.Name = name;
68
 
                        this.FullPathName = path;
69
 
                }
70
 
 
71
 
                public SourceFileEntry SourceFileEntry {
72
 
                        get {
73
 
                                return file;
74
 
                        }
75
 
                }
76
 
 
77
 
                public void SetChecksum (byte[] guid, byte[] checksum)
78
 
                {
79
 
                        this.guid = guid;
80
 
                        this.checksum = checksum;
81
 
                }
82
 
 
83
 
                public SourceFileEntry CreateSymbolInfo (MonoSymbolFile symwriter)
84
 
                {
85
 
                        if (hidden_lines != null)
86
 
                                hidden_lines.Sort ();
87
 
 
88
 
                        if (guid != null) {
89
 
                                file = new SourceFileEntry (symwriter, FullPathName, guid, checksum);
90
 
                        } else {
91
 
                                file = new SourceFileEntry (symwriter, FullPathName);
92
 
                                if (AutoGenerated)
93
 
                                        file.SetAutoGenerated ();
94
 
                        }
95
 
 
96
 
                        return file;
97
 
                }
98
 
 
99
 
                public bool Equals (SourceFile other)
100
 
                {
101
 
                        return FullPathName == other.FullPathName;
102
 
                }
103
 
 
104
 
                public bool IsHiddenLocation (Location loc)
105
 
                {
106
 
                        if (hidden_lines == null)
107
 
                                return false;
108
 
 
109
 
                        int index = hidden_lines.BinarySearch (new LocationRegion (loc, loc));
110
 
                        index = ~index;
111
 
                        if (index > 0) {
112
 
                                var found = hidden_lines[index - 1];
113
 
                                if (loc.Row < found.End.Row)
114
 
                                        return true;
115
 
                        }
116
 
 
117
 
                        return false;
118
 
                }
119
 
 
120
 
                public void RegisterHiddenScope (Location start, Location end)
121
 
                {
122
 
                        if (hidden_lines == null)
123
 
                                hidden_lines = new List<LocationRegion> ();
124
 
 
125
 
                        hidden_lines.Add (new LocationRegion (start, end));
126
 
                }
127
 
 
128
 
                public override string ToString ()
129
 
                {
130
 
                        return String.Format ("SourceFile ({0}:{1}:{2})", Name, FullPathName, Index);
131
 
                }
132
 
        }
133
 
 
134
 
        /// <summary>
135
 
        ///   Keeps track of the location in the program
136
 
        /// </summary>
137
 
        ///
138
 
        /// <remarks>
139
 
        ///   This uses a compact representation and a couple of auxiliary
140
 
        ///   structures to keep track of tokens to (file,line and column) 
141
 
        ///   mappings. The usage of the bits is:
142
 
        ///   
143
 
        ///     - 16 bits for "checkpoint" which is a mixed concept of
144
 
        ///       file and "line segment"
145
 
        ///     - 8 bits for line delta (offset) from the line segment
146
 
        ///     - 8 bits for column number.
147
 
        ///
148
 
        ///   http://lists.ximian.com/pipermail/mono-devel-list/2004-December/009508.html
149
 
        /// </remarks>
150
 
        public struct Location : IEquatable<Location>
151
 
        {
152
 
                struct Checkpoint {
153
 
                        public readonly int LineOffset;
154
 
                        public readonly int File;
155
 
 
156
 
                        public Checkpoint (int file, int line)
157
 
                        {
158
 
                                File = file;
159
 
                                LineOffset = line - (int) (line % (1 << line_delta_bits));
160
 
                        }
161
 
                }
162
 
 
163
 
#if FULL_AST
164
 
                readonly long token;
165
 
 
166
 
                const int column_bits = 24;
167
 
                const int line_delta_bits = 24;
168
 
#else
169
 
                readonly int token;
170
 
 
171
 
                const int column_bits = 8;
172
 
                const int line_delta_bits = 8;
173
 
#endif
174
 
                const int checkpoint_bits = 16;
175
 
 
176
 
                const int column_mask = (1 << column_bits) - 1;
177
 
                const int max_column = column_mask;
178
 
 
179
 
                static List<SourceFile> source_list;
180
 
                static int current_source;
181
 
                static Checkpoint [] checkpoints;
182
 
                static int checkpoint_index;
183
 
                
184
 
                public readonly static Location Null = new Location ();
185
 
                public static bool InEmacs;
186
 
                
187
 
                static Location ()
188
 
                {
189
 
                        Reset ();
190
 
                }
191
 
 
192
 
                public static void Reset ()
193
 
                {
194
 
                        source_list = new List<SourceFile> ();
195
 
                        current_source = 0;
196
 
                        checkpoint_index = 0;
197
 
                }
198
 
 
199
 
                public static void AddFile (SourceFile file)
200
 
                {
201
 
                        source_list.Add (file);
202
 
                }
203
 
 
204
 
                // <summary>
205
 
                //   After adding all source files we want to compile with AddFile(), this method
206
 
                //   must be called to `reserve' an appropriate number of bits in the token for the
207
 
                //   source file.  We reserve some extra space for files we encounter via #line
208
 
                //   directives while parsing.
209
 
                // </summary>
210
 
                static public void Initialize (List<SourceFile> files)
211
 
                {
212
 
#if NET_4_0 || MONODROID
213
 
                        source_list.AddRange (files);
214
 
#else
215
 
                        source_list.AddRange (files.ToArray ());
216
 
#endif
217
 
 
218
 
                        checkpoints = new Checkpoint [System.Math.Max (1, source_list.Count * 2)];
219
 
                        if (checkpoints.Length > 0)
220
 
                                checkpoints [0] = new Checkpoint (0, 0);
221
 
                }
222
 
 
223
 
                static public void Push (SourceFile file)
224
 
                {
225
 
                        current_source = file != null ? file.Index : -1;
226
 
                        // File is always pushed before being changed.
227
 
                }
228
 
                
229
 
                public Location (int row, int column)
230
 
                {
231
 
                        if (row <= 0)
232
 
                                token = 0;
233
 
                        else {
234
 
                                if (column > max_column)
235
 
                                        column = max_column;
236
 
 
237
 
                                long target = -1;
238
 
                                long delta = 0;
239
 
 
240
 
                                // FIXME: This value is certainly wrong but what was the intension
241
 
                                int max = checkpoint_index < 10 ?
242
 
                                        checkpoint_index : 10;
243
 
                                for (int i = 0; i < max; i++) {
244
 
                                        int offset = checkpoints [checkpoint_index - i].LineOffset;
245
 
                                        delta = row - offset;
246
 
                                        if (delta >= 0 &&
247
 
                                                delta < (1 << line_delta_bits) &&
248
 
                                                checkpoints [checkpoint_index - i].File == current_source) {
249
 
                                                target = checkpoint_index - i;
250
 
                                                break;
251
 
                                        }
252
 
                                }
253
 
                                if (target == -1) {
254
 
                                        AddCheckpoint (current_source, row);
255
 
                                        target = checkpoint_index;
256
 
                                        delta = row % (1 << line_delta_bits);
257
 
                                }
258
 
 
259
 
                                long l = column +
260
 
                                        (delta << column_bits) +
261
 
                                        (target << (line_delta_bits + column_bits));
262
 
#if FULL_AST
263
 
                                token = l;
264
 
#else
265
 
                                token = l > 0xFFFFFFFF ? 0 : (int) l;
266
 
#endif
267
 
                        }
268
 
                }
269
 
 
270
 
                public static Location operator - (Location loc, int columns)
271
 
                {
272
 
                        return new Location (loc.Row, loc.Column - columns);
273
 
                }
274
 
 
275
 
                static void AddCheckpoint (int file, int row)
276
 
                {
277
 
                        if (checkpoints.Length == ++checkpoint_index) {
278
 
                                Array.Resize (ref checkpoints, checkpoint_index * 2);
279
 
                        }
280
 
                        checkpoints [checkpoint_index] = new Checkpoint (file, row);
281
 
                }
282
 
 
283
 
                string FormatLocation (string fileName)
284
 
                {
285
 
                        if (column_bits == 0 || InEmacs)
286
 
                                return fileName + "(" + Row.ToString () + "):";
287
 
 
288
 
                        return fileName + "(" + Row.ToString () + "," + Column.ToString () +
289
 
                                (Column == max_column ? "+):" : "):");
290
 
                }
291
 
                
292
 
                public override string ToString ()
293
 
                {
294
 
                        return FormatLocation (Name);
295
 
                }
296
 
 
297
 
                public string ToStringFullName ()
298
 
                {
299
 
                        return FormatLocation (NameFullPath);
300
 
                }
301
 
                
302
 
                /// <summary>
303
 
                ///   Whether the Location is Null
304
 
                /// </summary>
305
 
                public bool IsNull {
306
 
                        get { return token == 0; }
307
 
                }
308
 
 
309
 
                public string Name {
310
 
                        get {
311
 
                                int index = File;
312
 
 
313
 
                                if (token == 0 || index <= 0)
314
 
                                        return null;
315
 
 
316
 
                                SourceFile file = source_list [index - 1];
317
 
                                return file.Name;
318
 
                        }
319
 
                }
320
 
 
321
 
                public string NameFullPath {
322
 
                        get {
323
 
                                int index = File;
324
 
                                if (token == 0 || index <= 0)
325
 
                                        return null;
326
 
 
327
 
                                return source_list[index - 1].FullPathName;
328
 
                        }
329
 
                }
330
 
 
331
 
                int CheckpointIndex {
332
 
                        get {
333
 
                                const int checkpoint_mask = (1 << checkpoint_bits) - 1;
334
 
                                return ((int) (token >> (line_delta_bits + column_bits))) & checkpoint_mask;
335
 
                        }
336
 
                }
337
 
 
338
 
                public int Row {
339
 
                        get {
340
 
                                if (token == 0)
341
 
                                        return 1;
342
 
 
343
 
                                int offset = checkpoints[CheckpointIndex].LineOffset;
344
 
 
345
 
                                const int line_delta_mask = (1 << column_bits) - 1;
346
 
                                return offset + (((int)(token >> column_bits)) & line_delta_mask);
347
 
                        }
348
 
                }
349
 
 
350
 
                public int Column {
351
 
                        get {
352
 
                                if (token == 0)
353
 
                                        return 1;
354
 
                                return (int) (token & column_mask);
355
 
                        }
356
 
                }
357
 
 
358
 
                public int File {
359
 
                        get {
360
 
                                if (token == 0)
361
 
                                        return 0;
362
 
if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format ("Should not happen. Token is {0:X04}, checkpoints are {1}, index is {2}", token, checkpoints.Length, CheckpointIndex));
363
 
                                return checkpoints [CheckpointIndex].File;
364
 
                        }
365
 
                }
366
 
 
367
 
                // The ISymbolDocumentWriter interface is used by the symbol writer to
368
 
                // describe a single source file - for each source file there's exactly
369
 
                // one corresponding ISymbolDocumentWriter instance.
370
 
                //
371
 
                // This class has an internal hash table mapping source document names
372
 
                // to such ISymbolDocumentWriter instances - so there's exactly one
373
 
                // instance per document.
374
 
                //
375
 
                // This property returns the ISymbolDocumentWriter instance which belongs
376
 
                // to the location's source file.
377
 
                //
378
 
                // If we don't have a symbol writer, this property is always null.
379
 
                public SourceFile SourceFile {
380
 
                        get {
381
 
                                int index = File;
382
 
                                if (index == 0)
383
 
                                        return null;
384
 
                                return source_list [index - 1];
385
 
                        }
386
 
                }
387
 
 
388
 
                #region IEquatable<Location> Members
389
 
 
390
 
                public bool Equals (Location other)
391
 
                {
392
 
                        return this.token == other.token;
393
 
                }
394
 
 
395
 
                #endregion
396
 
        }
397
 
        
398
 
        public class SpecialsBag
399
 
        {
400
 
                public enum CommentType
401
 
                {
402
 
                        Single,
403
 
                        Multi,
404
 
                        Documentation,
405
 
                        InactiveCode
406
 
                }
407
 
                
408
 
                public class Comment
409
 
                {
410
 
                        public readonly CommentType CommentType;
411
 
                        public readonly bool StartsLine;
412
 
                        public readonly int Line;
413
 
                        public readonly int Col;
414
 
                        public readonly int EndLine;
415
 
                        public readonly int EndCol;
416
 
                        public readonly string Content;
417
 
                        
418
 
                        public Comment (CommentType commentType, bool startsLine, int line, int col, int endLine, int endCol, string content)
419
 
                        {
420
 
                                this.CommentType = commentType;
421
 
                                this.StartsLine = startsLine;
422
 
                                this.Line = line;
423
 
                                this.Col = col;
424
 
                                this.EndLine = endLine;
425
 
                                this.EndCol = endCol;
426
 
                                this.Content = content;
427
 
                        }
428
 
 
429
 
                        public override string ToString ()
430
 
                        {
431
 
                                return string.Format ("[Comment: CommentType={0}, Line={1}, Col={2}, EndLine={3}, EndCol={4}, Content={5}]", CommentType, Line, Col, EndLine, EndCol, Content);
432
 
                        }
433
 
                }
434
 
                
435
 
                public class PreProcessorDirective
436
 
                {
437
 
                        public readonly int Line;
438
 
                        public readonly int Col;
439
 
                        public readonly int EndLine;
440
 
                        public readonly int EndCol;
441
 
 
442
 
                        public readonly Tokenizer.PreprocessorDirective Cmd;
443
 
                        public readonly string Arg;
444
 
                        
445
 
                        public bool Take = true;
446
 
                        
447
 
                        public PreProcessorDirective (int line, int col, int endLine, int endCol, Tokenizer.PreprocessorDirective cmd, string arg)
448
 
                        {
449
 
                                this.Line = line;
450
 
                                this.Col = col;
451
 
                                this.EndLine = endLine;
452
 
                                this.EndCol = endCol;
453
 
                                this.Cmd = cmd;
454
 
                                this.Arg = arg;
455
 
                        }
456
 
                        
457
 
                        public override string ToString ()
458
 
                        {
459
 
                                return string.Format ("[PreProcessorDirective: Line={0}, Col={1}, EndLine={2}, EndCol={3}, Cmd={4}, Arg={5}]", Line, Col, EndLine, EndCol, Cmd, Arg);
460
 
                        }
461
 
                }
462
 
                
463
 
                public readonly List<object> Specials = new List<object> ();
464
 
                
465
 
                CommentType curComment;
466
 
                bool startsLine;
467
 
                int startLine, startCol;
468
 
                System.Text.StringBuilder contentBuilder = new System.Text.StringBuilder ();
469
 
                
470
 
                [Conditional ("FULL_AST")]
471
 
                public void StartComment (CommentType type, bool startsLine, int startLine, int startCol)
472
 
                {
473
 
                        inComment = true;
474
 
                        curComment = type;
475
 
                        this.startsLine = startsLine;
476
 
                        this.startLine = startLine;
477
 
                        this.startCol = startCol;
478
 
                        contentBuilder.Length = 0;
479
 
                }
480
 
                
481
 
                [Conditional ("FULL_AST")]
482
 
                public void PushCommentChar (int ch)
483
 
                {
484
 
                        if (ch < 0)
485
 
                                return;
486
 
                        contentBuilder.Append ((char)ch);
487
 
                }
488
 
                [Conditional ("FULL_AST")]
489
 
                public void PushCommentString (string str)
490
 
                {
491
 
                        contentBuilder.Append (str);
492
 
                }
493
 
                
494
 
                bool inComment;
495
 
                [Conditional ("FULL_AST")]
496
 
                public void EndComment (int endLine, int endColumn)
497
 
                {
498
 
                        if (!inComment)
499
 
                                return;
500
 
                        inComment = false;
501
 
                        Specials.Add (new Comment (curComment, startsLine, startLine, startCol, endLine, endColumn, contentBuilder.ToString ()));
502
 
                }
503
 
                
504
 
                [Conditional ("FULL_AST")]
505
 
                public void AddPreProcessorDirective (int startLine, int startCol, int endLine, int endColumn, Tokenizer.PreprocessorDirective cmd, string arg)
506
 
                {
507
 
                        if (inComment)
508
 
                                EndComment (startLine, startCol);
509
 
                        Specials.Add (new PreProcessorDirective (startLine, startCol, endLine, endColumn, cmd, arg));
510
 
                }
511
 
 
512
 
                public void SkipIf ()
513
 
                {
514
 
                        if (Specials.Count > 0) {
515
 
                                var directive = Specials[Specials.Count - 1] as PreProcessorDirective;
516
 
                                if (directive != null)
517
 
                                        directive.Take = false;
518
 
                        }
519
 
                }
520
 
        }
521
 
 
522
 
        //
523
 
        // A bag of additional locations to support full ast tree
524
 
        //
525
 
        public class LocationsBag
526
 
        {
527
 
                public class MemberLocations
528
 
                {
529
 
                        public IList<Tuple<Modifiers, Location>> Modifiers { get; internal set; }
530
 
                        List<Location> locations;
531
 
                        
532
 
                        public MemberLocations (IList<Tuple<Modifiers, Location>> mods, IEnumerable<Location> locs)
533
 
                        {
534
 
                                Modifiers = mods;
535
 
                                locations = locs != null ?  new List<Location> (locs) : null;
536
 
                        }
537
 
 
538
 
                        #region Properties
539
 
 
540
 
                        public Location this [int index] {
541
 
                                get {
542
 
                                        return locations [index];
543
 
                                }
544
 
                        }
545
 
                        
546
 
                        public int Count {
547
 
                                get {
548
 
                                        return locations != null ? locations.Count : 0;
549
 
                                }
550
 
                        }
551
 
 
552
 
                        #endregion
553
 
 
554
 
                        public void AddLocations (params Location[] additional)
555
 
 
556
 
                        {
557
 
 
558
 
                                AddLocations ((IEnumerable<Location>)additional);
559
 
 
560
 
                        }
561
 
                        public void AddLocations (IEnumerable<Location> additional)
562
 
                        {
563
 
                                if (additional == null)
564
 
                                        return;
565
 
                                if (locations == null) {
566
 
                                        locations = new List<Location>(additional);
567
 
                                } else {
568
 
                                        locations.AddRange (additional);
569
 
                                }
570
 
                        }
571
 
                }
572
 
                
573
 
                public MemberCore LastMember {
574
 
                        get;
575
 
                        private set;
576
 
                }
577
 
 
578
 
                Dictionary<object, List<Location>> simple_locs = new Dictionary<object,  List<Location>> (ReferenceEquality<object>.Default);
579
 
                Dictionary<MemberCore, MemberLocations> member_locs = new Dictionary<MemberCore, MemberLocations> (ReferenceEquality<MemberCore>.Default);
580
 
 
581
 
                [Conditional ("FULL_AST")]
582
 
                public void AddLocation (object element, params Location[] locations)
583
 
                {
584
 
                        AddLocation (element, (IEnumerable<Location>)locations);
585
 
                }
586
 
 
587
 
                [Conditional ("FULL_AST")]
588
 
                public void AddLocation (object element, IEnumerable<Location> locations)
589
 
                {
590
 
                        if (element == null || locations == null)
591
 
                                return;
592
 
                        simple_locs.Add (element, new List<Location> (locations));
593
 
                }
594
 
 
595
 
                [Conditional ("FULL_AST")]
596
 
                public void AddStatement (object element, params Location[] locations)
597
 
                {
598
 
                        if (element == null)
599
 
                                return;
600
 
                        if (locations.Length == 0)
601
 
                                throw new ArgumentException ("Statement is missing semicolon location");
602
 
                        simple_locs.Add (element, new List<Location>(locations));
603
 
                }
604
 
 
605
 
                [Conditional ("FULL_AST")]
606
 
                public void AddMember (MemberCore member, IList<Tuple<Modifiers, Location>> modLocations, params Location[] locations)
607
 
                {
608
 
                        LastMember = member;
609
 
                        if (member == null)
610
 
                                return;
611
 
                        
612
 
                        MemberLocations existing;
613
 
                        if (member_locs.TryGetValue (member, out existing)) {
614
 
                                existing.Modifiers = modLocations;
615
 
                                existing.AddLocations (locations);
616
 
                                return;
617
 
                        }
618
 
                        member_locs.Add (member, new MemberLocations (modLocations, locations));
619
 
                }
620
 
                [Conditional ("FULL_AST")]
621
 
                public void AddMember (MemberCore member, IList<Tuple<Modifiers, Location>> modLocations, IEnumerable<Location> locations)
622
 
                {
623
 
                        LastMember = member;
624
 
                        if (member == null)
625
 
                                return;
626
 
                        
627
 
                        MemberLocations existing;
628
 
                        if (member_locs.TryGetValue (member, out existing)) {
629
 
                                existing.Modifiers = modLocations;
630
 
                                existing.AddLocations (locations);
631
 
                                return;
632
 
                        }
633
 
                        member_locs.Add (member, new MemberLocations (modLocations, locations));
634
 
                }
635
 
 
636
 
                [Conditional ("FULL_AST")]
637
 
                public void AppendTo (object existing, params Location[] locations)
638
 
                {
639
 
                        AppendTo (existing, (IEnumerable<Location>)locations);
640
 
 
641
 
                }
642
 
 
643
 
                [Conditional ("FULL_AST")]
644
 
                public void AppendTo (object existing, IEnumerable<Location> locations)
645
 
                {
646
 
                        if (existing == null)
647
 
                                return;
648
 
                        List<Location> locs;
649
 
                        if (simple_locs.TryGetValue (existing, out locs)) {
650
 
                                simple_locs [existing].AddRange (locations);
651
 
                                return;
652
 
                        }
653
 
                        AddLocation (existing, locations);
654
 
                }
655
 
                
656
 
                [Conditional ("FULL_AST")]
657
 
                public void AppendToMember (MemberCore existing, params Location[] locations)
658
 
                {
659
 
                        AppendToMember (existing, (IEnumerable<Location>)locations);
660
 
 
661
 
                }
662
 
                
663
 
                [Conditional ("FULL_AST")]
664
 
                public void AppendToMember (MemberCore existing, IEnumerable<Location> locations)
665
 
                {
666
 
                        if (existing == null)
667
 
                                return;
668
 
                        MemberLocations member;
669
 
                        if (member_locs.TryGetValue (existing, out member)) {
670
 
                                member.AddLocations (locations);
671
 
                                return;
672
 
                        }
673
 
                        member_locs.Add (existing, new MemberLocations (null, locations));
674
 
                }
675
 
 
676
 
                public List<Location> GetLocations (object element)
677
 
                {
678
 
                        if (element == null)
679
 
                                return null;
680
 
                        List<Location > found;
681
 
                        simple_locs.TryGetValue (element, out found);
682
 
                        return found;
683
 
                }
684
 
 
685
 
                public MemberLocations GetMemberLocation (MemberCore element)
686
 
                {
687
 
                        MemberLocations found;
688
 
                        member_locs.TryGetValue (element, out found);
689
 
                        return found;
690
 
                }
691
 
        }
692
 
}