Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/xamarin/NRefactory.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Krüger <mkrueger@xamarin.com>2013-09-19 22:10:40 +0400
committerMike Krüger <mkrueger@xamarin.com>2013-09-19 22:10:40 +0400
commit2442a71d3c62089e6297ad41fb74d784ebb3326e (patch)
tree7bf307f987dde9cc43aa222b570841a0439b525f /ICSharpCode.NRefactory.IKVM
parent6d88b6a8fbdc678ccf5f35c2e3ce9ca45e4ea6e5 (diff)
Implemented special interning provider.
Diffstat (limited to 'ICSharpCode.NRefactory.IKVM')
-rw-r--r--ICSharpCode.NRefactory.IKVM/FastInterningProvider.cs130
-rw-r--r--ICSharpCode.NRefactory.IKVM/ICSharpCode.NRefactory.IKVM.csproj1
-rw-r--r--ICSharpCode.NRefactory.IKVM/IkvmLoader.cs1
3 files changed, 132 insertions, 0 deletions
diff --git a/ICSharpCode.NRefactory.IKVM/FastInterningProvider.cs b/ICSharpCode.NRefactory.IKVM/FastInterningProvider.cs
new file mode 100644
index 00000000..5effc8dd
--- /dev/null
+++ b/ICSharpCode.NRefactory.IKVM/FastInterningProvider.cs
@@ -0,0 +1,130 @@
+// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this
+// software and associated documentation files (the "Software"), to deal in the Software
+// without restriction, including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
+// to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or
+// substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Runtime.CompilerServices;
+
+using ICSharpCode.NRefactory.Utils;
+
+namespace ICSharpCode.NRefactory.TypeSystem.Implementation
+{
+ /// <summary>
+ /// Fast interning provider. The main difference is that it only supports to intern non frozen objects.
+ /// </summary>
+ sealed class FastInterningProvider : InterningProvider
+ {
+ sealed class ListComparer : IEqualityComparer<IEnumerable>
+ {
+ public bool Equals(IEnumerable a, IEnumerable b)
+ {
+ if (a.GetType() != b.GetType())
+ return false;
+ IEnumerator e1 = a.GetEnumerator();
+ IEnumerator e2 = b.GetEnumerator();
+ while (e1.MoveNext()) {
+ // e1 has more elements than e2; or elements are different
+ if (!e2.MoveNext() || e1.Current != e2.Current)
+ return false;
+ }
+ if (e2.MoveNext()) // e2 has more elements than e1
+ return false;
+ // No need to dispose e1/e2: non-generic IEnumerator doesn't implement IDisposable,
+ // and the underlying enumerator will likely be a List<T>.Enumerator which has an empty Dispose() method.
+ return true;
+ }
+
+ public int GetHashCode(IEnumerable obj)
+ {
+ int hashCode = obj.GetType().GetHashCode();
+ unchecked {
+ foreach (object o in obj) {
+ hashCode *= 27;
+ hashCode += RuntimeHelpers.GetHashCode(o);
+ }
+ }
+ return hashCode;
+ }
+ }
+
+ Dictionary<object, object> byValueDict = new Dictionary<object, object>();
+ Dictionary<int, ISupportsInterning> supportsInternDict = new Dictionary<int, ISupportsInterning>();
+ Dictionary<IEnumerable, IEnumerable> listDict = new Dictionary<IEnumerable, IEnumerable>(new ListComparer());
+
+ public override ISupportsInterning Intern(ISupportsInterning obj)
+ {
+ if (obj == null)
+ return null;
+
+ ISupportsInterning output;
+ var hashCode = obj.GetHashCodeForInterning ();
+ if (supportsInternDict.TryGetValue(hashCode, out output)) {
+ return output;
+ } else {
+ // ensure objects are frozen when we put them into the dictionary
+ // note that Freeze may change the hash code of the object
+ FreezableHelper.Freeze(obj);
+ supportsInternDict.Add (hashCode, obj);
+ return obj;
+ }
+ }
+
+ public override string Intern(string text)
+ {
+ if (text == null)
+ return null;
+
+ object output;
+ if (byValueDict.TryGetValue(text, out output))
+ return (string)output;
+ else
+ return text;
+ }
+
+ public override object InternValue(object obj)
+ {
+ if (obj == null)
+ return null;
+
+ object output;
+ if (byValueDict.TryGetValue(obj, out output))
+ return output;
+ else
+ return obj;
+ }
+
+ public override IList<T> InternList<T>(IList<T> list)
+ {
+ if (list == null)
+ return null;
+ if (list.Count == 0)
+ return EmptyList<T>.Instance;
+ if (!list.IsReadOnly)
+ list = new ReadOnlyCollection<T>(list);
+ IEnumerable output;
+ if (listDict.TryGetValue(list, out output))
+ list = (IList<T>)output;
+ else
+ listDict.Add(list, list);
+ return list;
+ }
+ }
+}
diff --git a/ICSharpCode.NRefactory.IKVM/ICSharpCode.NRefactory.IKVM.csproj b/ICSharpCode.NRefactory.IKVM/ICSharpCode.NRefactory.IKVM.csproj
index 8ef5b98e..ea42305a 100644
--- a/ICSharpCode.NRefactory.IKVM/ICSharpCode.NRefactory.IKVM.csproj
+++ b/ICSharpCode.NRefactory.IKVM/ICSharpCode.NRefactory.IKVM.csproj
@@ -44,6 +44,7 @@
<Compile Include="IntConstantValue.cs" />
<Compile Include="StructConstantValue.cs" />
<Compile Include="ShortConstantValue.cs" />
+ <Compile Include="FastInterningProvider.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
diff --git a/ICSharpCode.NRefactory.IKVM/IkvmLoader.cs b/ICSharpCode.NRefactory.IKVM/IkvmLoader.cs
index 9d73743f..92d5ccf2 100644
--- a/ICSharpCode.NRefactory.IKVM/IkvmLoader.cs
+++ b/ICSharpCode.NRefactory.IKVM/IkvmLoader.cs
@@ -74,6 +74,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// </summary>
public IkvmLoader()
{
+ interningProvider = new FastInterningProvider ();
}
#region Load Assembly From Disk