+
+ public CompilationUnit CompilationUnit {
+ get {
+ int index = CompilationUnitIndex;
+ if (index == 0)
+ return null;
+ return (CompilationUnit) source_list [index - 1];
+ }
+ }
+ }
+
+ //
+ // A bag of additional locations to support full ast tree
+ //
+ public class LocationsBag
+ {
+ public class MemberLocations
+ {
+ public readonly IList<Tuple<Modifiers, Location>> Modifiers;
+ Location[] locations;
+
+ public MemberLocations (IList<Tuple<Modifiers, Location>> mods, Location[] locs)
+ {
+ Modifiers = mods;
+ locations = locs;
+ }
+
+ #region Properties
+
+ public Location this [int index] {
+ get {
+ return locations [index];
+ }
+ }
+
+ public int Count {
+ get {
+ return locations.Length;
+ }
+ }
+
+ #endregion
+
+ public void AddLocations (params Location[] additional)
+ {
+ if (locations == null) {
+ locations = additional;
+ } else {
+ int pos = locations.Length;
+ Array.Resize (ref locations, pos + additional.Length);
+ additional.CopyTo (locations, pos);
+ }
+ }
+ }
+
+ Dictionary<object, Location[]> simple_locs = new Dictionary<object, Location[]> (ReferenceEquality<object>.Default);
+ Dictionary<MemberCore, MemberLocations> member_locs = new Dictionary<MemberCore, MemberLocations> (ReferenceEquality<MemberCore>.Default);
+
+ [Conditional ("FULL_AST")]
+ public void AddLocation (object element, params Location[] locations)
+ {
+ simple_locs.Add (element, locations);
+ }
+
+ [Conditional ("FULL_AST")]
+ public void AddStatement (object element, params Location[] locations)
+ {
+ if (locations.Length == 0)
+ throw new ArgumentException ("Statement is missing semicolon location");
+
+ simple_locs.Add (element, locations);
+ }
+
+ [Conditional ("FULL_AST")]
+ public void AddMember (MemberCore member, IList<Tuple<Modifiers, Location>> modLocations, params Location[] locations)
+ {
+ member_locs.Add (member, new MemberLocations (modLocations, locations));
+ }
+
+ [Conditional ("FULL_AST")]
+ public void AppendTo (object existing, params Location[] locations)
+ {
+ Location[] locs;
+ if (simple_locs.TryGetValue (existing, out locs)) {
+ simple_locs [existing] = locs.Concat (locations).ToArray ();
+ return;
+ }
+ }
+
+ [Conditional ("FULL_AST")]
+ public void AppendToMember (MemberCore existing, params Location[] locations)
+ {
+ MemberLocations member;
+ if (member_locs.TryGetValue (existing, out member)) {
+ member.AddLocations (locations);
+ return;
+ }
+ }
+
+ public Location[] GetLocations (object element)
+ {
+ Location[] found;
+ simple_locs.TryGetValue (element, out found);
+ return found;
+ }
+
+ public MemberLocations GetMemberLocation (MemberCore element)
+ {
+ MemberLocations found;
+ member_locs.TryGetValue (element, out found);
+ return found;
+ }