// Author:
// Miguel de Icaza
// Atsushi Enomoto <atsushi@ximian.com>
+// Marek Safar (marek.safar@gmail.com)
//
// Copyright 2001 Ximian, Inc.
// Copyright 2005 Novell, Inc.
using System;
using System.IO;
-using System.Collections;
+using System.Collections.Generic;
using Mono.CompilerServices.SymbolWriter;
+using System.Diagnostics;
+using System.Linq;
namespace Mono.CSharp {
/// <summary>
public class CompilationUnit : SourceFile, ICompileUnit
{
CompileUnitEntry comp_unit;
- Hashtable include_files;
- Hashtable conditionals;
+ Dictionary<string, SourceFile> include_files;
+ Dictionary<string, bool> conditionals;
public CompilationUnit (string name, string path, int index)
: base (name, path, index, false)
public void AddFile (SourceFile file)
{
+ if (file == this)
+ return;
+
if (include_files == null)
- include_files = new Hashtable ();
+ include_files = new Dictionary<string, SourceFile> ();
- if (!include_files.Contains (file.Path))
+ if (!include_files.ContainsKey (file.Path))
include_files.Add (file.Path, file);
}
public void AddDefine (string value)
{
if (conditionals == null)
- conditionals = new Hashtable (2);
+ conditionals = new Dictionary<string, bool> (2);
conditionals [value] = true;
}
public void AddUndefine (string value)
{
if (conditionals == null)
- conditionals = new Hashtable (2);
+ conditionals = new Dictionary<string, bool> (2);
- conditionals [value] = null;
+ conditionals [value] = false;
}
CompileUnitEntry ICompileUnit.Entry {
public bool IsConditionalDefined (string value)
{
if (conditionals != null) {
- object res = conditionals [value];
- if (res != null)
- return (bool)res;
+ bool res;
+ if (conditionals.TryGetValue (value, out res))
+ return res;
+
+ // When conditional was undefined
+ if (conditionals.ContainsKey (value))
+ return false;
}
return RootContext.IsConditionalDefined (value);
}
}
- static ArrayList source_list;
- static ArrayList compile_units;
- static Hashtable source_files;
+ static List<SourceFile> source_list;
+ static List<CompilationUnit> compile_units;
+ static Dictionary<string, int> source_files;
static int checkpoint_bits;
static int source_count;
static int current_source;
static Location ()
{
- source_files = new Hashtable ();
- source_list = new ArrayList ();
- compile_units = new ArrayList ();
- current_source = 0;
- current_compile_unit = 0;
+ Reset ();
checkpoints = new Checkpoint [10];
}
public static void Reset ()
{
- source_files = new Hashtable ();
- source_list = new ArrayList ();
- compile_units = new ArrayList ();
+ source_files = new Dictionary<string, int> ();
+ source_list = new List<SourceFile> ();
+ compile_units = new List<CompilationUnit> ();
current_source = 0;
current_compile_unit = 0;
source_count = 0;
// <summary>
// This must be called before parsing/tokenizing any files.
// </summary>
- static public void AddFile (string name)
+ static public void AddFile (Report r, string name)
{
string path = Path.GetFullPath (name);
-
- if (source_files.Contains (path)){
- int id = (int) source_files [path];
- string other_name = ((SourceFile) source_list [id - 1]).Name;
+ int id;
+ if (source_files.TryGetValue (path, out id)){
+ string other_name = source_list [id - 1].Name;
if (name.Equals (other_name))
- Report.Warning (2002, 1, "Source file `{0}' specified multiple times", other_name);
+ r.Warning (2002, 1, "Source file `{0}' specified multiple times", other_name);
else
- Report.Warning (2002, 1, "Source filenames `{0}' and `{1}' both refer to the same file: {2}", name, other_name, path);
+ r.Warning (2002, 1, "Source filenames `{0}' and `{1}' both refer to the same file: {2}", name, other_name, path);
return;
}
compile_units.Add (unit);
}
- static public CompilationUnit[] SourceFiles {
+ public static IList<CompilationUnit> SourceFiles {
get {
- CompilationUnit[] retval = new CompilationUnit [compile_units.Count];
- compile_units.CopyTo (retval, 0);
- return retval;
+ return compile_units;
}
}
} else
path = name;
- if (!source_files.Contains (path)) {
+ if (!source_files.ContainsKey (path)) {
if (source_count >= (1 << checkpoint_bits))
return new SourceFile (name, path, 0, true);
}
}
+ public static Location operator - (Location loc, int columns)
+ {
+ return new Location (loc.Row, loc.Column - columns);
+ }
+
static void AddCheckpoint (int compile_unit, int file, int row)
{
if (checkpoints.Length == ++checkpoint_index) {
}
}
- public class LocatedToken
+ //
+ // A bag of additional locations to support full ast tree
+ //
+ public class LocationsBag
{
- public readonly Location Location;
- public readonly string Value;
+ 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);
- public LocatedToken (Location loc, string value)
+ [Conditional ("FULL_AST")]
+ public void AddLocation (object element, params Location[] locations)
{
- Location = loc;
- Value = value;
+ simple_locs.Add (element, locations);
}
- public override string ToString ()
+ [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)
{
- return Location.ToString () + Value;
+ MemberLocations found;
+ member_locs.TryGetValue (element, out found);
+ return found;
}
}
}