Merge
[mono.git] / mcs / mcs / location.cs
index 8b3e6f2432f59786bec0de23e6495a008e34c658..229cc7d25959fdfc659988372aeeee43f1c6fc5d 100644 (file)
@@ -11,7 +11,6 @@
 //
 
 using System;
-using System.IO;
 using System.Collections.Generic;
 using Mono.CompilerServices.SymbolWriter;
 using System.Diagnostics;
@@ -19,6 +18,12 @@ using System.Linq;
 
 namespace Mono.CSharp
 {
+       public enum SourceFileType 
+       {
+               CSharp = 0,
+               PlayScript
+       }
+       
        //
        //  This is one single source file.
        //
@@ -53,13 +58,16 @@ namespace Mono.CSharp
                        }
                }
 
+               static readonly byte[] MD5Algorith = { 96, 166, 110, 64, 207, 100, 130, 76, 182, 240, 66, 212, 129, 114, 167, 153 };
+
                public readonly string Name;
                public readonly string FullPathName;
                public readonly int Index;
                public bool AutoGenerated;
+               readonly SourceFileType FileType;
 
                SourceFileEntry file;
-               byte[] guid, checksum;
+               byte[] algGuid, checksum;
                List<LocationRegion> hidden_lines;
 
                public SourceFile (string name, string path, int index)
@@ -67,6 +75,27 @@ namespace Mono.CSharp
                        this.Index = index;
                        this.Name = name;
                        this.FullPathName = path;
+
+                       if (name.EndsWith (".play", StringComparison.Ordinal) || name.EndsWith (".asx", StringComparison.Ordinal))
+                               FileType = SourceFileType.PlayScript;
+               }
+
+               public byte[] Checksum {
+                       get {
+                               return checksum;
+                       }
+               }
+
+               public bool HasChecksum {
+                       get {
+                               return checksum != null;
+                       }
+               }
+
+               public bool IsPlayScript {
+                       get {
+                               return FileType == SourceFileType.PlayScript;
+                       }
                }
 
                public SourceFileEntry SourceFileEntry {
@@ -75,24 +104,25 @@ namespace Mono.CSharp
                        }
                }
 
-               public void SetChecksum (byte[] guid, byte[] checksum)
+               public void SetChecksum (byte[] checksum)
                {
-                       this.guid = guid;
+                       SetChecksum (MD5Algorith, checksum);
+               }
+
+               public void SetChecksum (byte[] algorithmGuid, byte[] checksum)
+               {
+                       this.algGuid = algorithmGuid;
                        this.checksum = checksum;
                }
 
-               public SourceFileEntry CreateSymbolInfo (MonoSymbolWriter symwriter)
+               public SourceFileEntry CreateSymbolInfo (MonoSymbolFile symwriter)
                {
                        if (hidden_lines != null)
                                hidden_lines.Sort ();
 
-                       if (guid != null)
-                               file = symwriter.DefineDocument (FullPathName, guid, checksum);
-                       else {
-                               file = symwriter.DefineDocument (FullPathName);
-                               if (AutoGenerated)
-                                       file.SetAutoGenerated ();
-                       }
+                       file = new SourceFileEntry (symwriter, FullPathName, algGuid, checksum);
+                       if (AutoGenerated)
+                               file.SetAutoGenerated ();
 
                        return file;
                }
@@ -178,7 +208,6 @@ namespace Mono.CSharp
                const int max_column = column_mask;
 
                static List<SourceFile> source_list;
-               static int current_source;
                static Checkpoint [] checkpoints;
                static int checkpoint_index;
                
@@ -193,7 +222,6 @@ namespace Mono.CSharp
                public static void Reset ()
                {
                        source_list = new List<SourceFile> ();
-                       current_source = 0;
                        checkpoint_index = 0;
                }
 
@@ -210,7 +238,7 @@ namespace Mono.CSharp
                // </summary>
                static public void Initialize (List<SourceFile> files)
                {
-#if NET_4_0
+#if NET_4_0 || MONODROID
                        source_list.AddRange (files);
 #else
                        source_list.AddRange (files.ToArray ());
@@ -221,13 +249,7 @@ namespace Mono.CSharp
                                checkpoints [0] = new Checkpoint (0, 0);
                }
 
-               static public void Push (SourceFile file)
-               {
-                       current_source = file != null ? file.Index : -1;
-                       // File is always pushed before being changed.
-               }
-               
-               public Location (int row, int column)
+               public Location (SourceFile file, int row, int column)
                {
                        if (row <= 0)
                                token = 0;
@@ -238,6 +260,9 @@ namespace Mono.CSharp
                                long target = -1;
                                long delta = 0;
 
+                               // TODO: For eval only, need better handling of empty
+                               int file_index = file == null ? 0 : file.Index;
+
                                // FIXME: This value is certainly wrong but what was the intension
                                int max = checkpoint_index < 10 ?
                                        checkpoint_index : 10;
@@ -246,13 +271,13 @@ namespace Mono.CSharp
                                        delta = row - offset;
                                        if (delta >= 0 &&
                                                delta < (1 << line_delta_bits) &&
-                                               checkpoints [checkpoint_index - i].File == current_source) {
+                                               checkpoints[checkpoint_index - i].File == file_index) {
                                                target = checkpoint_index - i;
                                                break;
                                        }
                                }
                                if (target == -1) {
-                                       AddCheckpoint (current_source, row);
+                                       AddCheckpoint (file_index, row);
                                        target = checkpoint_index;
                                        delta = row % (1 << line_delta_bits);
                                }
@@ -270,7 +295,7 @@ namespace Mono.CSharp
 
                public static Location operator - (Location loc, int columns)
                {
-                       return new Location (loc.Row, loc.Column - columns);
+                       return new Location (loc.SourceFile, loc.Row, loc.Column - columns);
                }
 
                static void AddCheckpoint (int file, int row)
@@ -403,11 +428,28 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format ("
                public class MemberLocations
                {
                        public readonly IList<Tuple<Modifiers, Location>> Modifiers;
-                       Location[] locations;
+                       List<Location> locations;
 
-                       public MemberLocations (IList<Tuple<Modifiers, Location>> mods, Location[] locs)
+                       public MemberLocations (IList<Tuple<Modifiers, Location>> mods)
                        {
                                Modifiers = mods;
+                       }
+
+                       public MemberLocations (IList<Tuple<Modifiers, Location>> mods, Location loc)
+                               : this (mods)
+                       {
+                               AddLocations (loc);
+                       }
+
+                       public MemberLocations (IList<Tuple<Modifiers, Location>> mods, Location[] locs)
+                               : this (mods)
+                       {
+                               AddLocations (locs);
+                       }
+
+                       public MemberLocations (IList<Tuple<Modifiers, Location>> mods, List<Location> locs)
+                               : this (mods)
+                       {
                                locations = locs;
                        }
 
@@ -421,31 +463,50 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format ("
                        
                        public int Count {
                                get {
-                                       return locations.Length;
+                                       return locations.Count;
                                }
                        }
 
                        #endregion
 
+                       public void AddLocations (Location loc)
+                       {
+                               if (locations == null) {
+                                       locations = new List<Location> ();
+                               }
+
+                               locations.Add (loc);
+                       }
+
                        public void AddLocations (params Location[] additional)
                        {
                                if (locations == null) {
-                                       locations = additional;
+                                       locations = new List<Location> (additional);
                                } else {
-                                       int pos = locations.Length;
-                                       Array.Resize (ref locations, pos + additional.Length);
-                                       additional.CopyTo (locations, pos);
+                                       locations.AddRange (additional);
                                }
                        }
                }
 
-               Dictionary<object, Location[]> simple_locs = new Dictionary<object, Location[]> (ReferenceEquality<object>.Default);
+               Dictionary<object, List<Location>> simple_locs = new Dictionary<object, List<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);
+                       simple_locs.Add (element, new List<Location> (locations));
+               }
+
+               [Conditional ("FULL_AST")]
+               public void InsertLocation (object element, int index, Location location)
+               {
+                       List<Location> found;
+                       if (!simple_locs.TryGetValue (element, out found)) {
+                               found = new List<Location> ();
+                               simple_locs.Add (element, found);
+                       }
+
+                       found.Insert (index, location);
                }
 
                [Conditional ("FULL_AST")]
@@ -454,7 +515,19 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format ("
                        if (locations.Length == 0)
                                throw new ArgumentException ("Statement is missing semicolon location");
 
-                       simple_locs.Add (element, locations);
+                       AddLocation (element, locations);
+               }
+
+               [Conditional ("FULL_AST")]
+               public void AddMember (MemberCore member, IList<Tuple<Modifiers, Location>> modLocations)
+               {
+                       member_locs.Add (member, new MemberLocations (modLocations));
+               }
+
+               [Conditional ("FULL_AST")]
+               public void AddMember (MemberCore member, IList<Tuple<Modifiers, Location>> modLocations, Location location)
+               {
+                       member_locs.Add (member, new MemberLocations (modLocations, location));
                }
 
                [Conditional ("FULL_AST")]
@@ -464,13 +537,21 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format ("
                }
 
                [Conditional ("FULL_AST")]
-               public void AppendTo (object existing, params Location[] locations)
+               public void AddMember (MemberCore member, IList<Tuple<Modifiers, Location>> modLocations, List<Location> locations)
                {
-                       Location[] locs;
-                       if (simple_locs.TryGetValue (existing, out locs)) {
-                               simple_locs [existing] = locs.Concat (locations).ToArray ();
-                               return;
+                       member_locs.Add (member, new MemberLocations (modLocations, locations));
+               }
+
+               [Conditional ("FULL_AST")]
+               public void AppendTo (object element, Location location)
+               {
+                       List<Location> found;
+                       if (!simple_locs.TryGetValue (element, out found)) {
+                               found = new List<Location> ();
+                               simple_locs.Add (element, found);
                        }
+
+                       found.Add (location);
                }
 
                [Conditional ("FULL_AST")]
@@ -483,9 +564,9 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format ("
                        }
                }
 
-               public Location[] GetLocations (object element)
+               public List<Location> GetLocations (object element)
                {
-                       Location[] found;
+                       List<Location> found;
                        simple_locs.TryGetValue (element, out found);
                        return found;
                }