diff --git a/ICSharpCode.NRefactory.Tests/TypeSystem/TestInterningProvider.cs b/ICSharpCode.NRefactory.Tests/TypeSystem/TestInterningProvider.cs index 44cd8adf48..b21c31b49e 100644 --- a/ICSharpCode.NRefactory.Tests/TypeSystem/TestInterningProvider.cs +++ b/ICSharpCode.NRefactory.Tests/TypeSystem/TestInterningProvider.cs @@ -74,12 +74,16 @@ namespace ICSharpCode.NRefactory.TypeSystem uniqueObjectsPreIntern.Add(obj); ISupportsInterning s = obj as ISupportsInterning; if (s != null) { - s.PrepareForInterning(this); ISupportsInterning output; - if (supportsInternDict.TryGetValue(s, out output)) + if (supportsInternDict.TryGetValue(s, out output)) { obj = (T)output; - else - supportsInternDict.Add(s, s); + } else { + s.PrepareForInterning(this); + if (supportsInternDict.TryGetValue(s, out output)) + obj = (T)output; + else + supportsInternDict.Add(s, s); + } } else if (obj is string || obj is IType || obj is bool || obj is int) { object output; if (byValueDict.TryGetValue(obj, out output)) diff --git a/ICSharpCode.NRefactory/TypeSystem/IInterningProvider.cs b/ICSharpCode.NRefactory/TypeSystem/IInterningProvider.cs index 7e77fa5fb3..3e8f456553 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IInterningProvider.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IInterningProvider.cs @@ -7,6 +7,24 @@ using System.Diagnostics.Contracts; namespace ICSharpCode.NRefactory.TypeSystem { + /// + /// Provider used for interning. + /// + /// + /// A simple IInterningProvider implementation could use 3 dictionaries: + /// 1. using value equality comparer (for certain types known to implement value equality, e.g. string and IType) + /// 2. using comparer that calls into ISupportsInterning (for types implementing ISupportsInterning) + /// 3. list comparer (for InternList method) + /// + /// On the first Intern()-call, the provider tells the object to prepare for interning (ISupportsInterning.PrepareForInterning) + /// and stores it into a dictionary. On further Intern() calls, the original object is returned for all equal objects. + /// This allows reducing the memory usage by using a single object instance where possible. + /// + /// Interning provider implementations could also use the interning logic for different purposes: + /// for example, it could be used to determine which objects are used jointly between multiple type definitions + /// and which are used only within a single type definition. Then a persistent file format could be organized so + /// that shared objects are loaded only once, yet non-shared objects get loaded lazily together with the class. + /// [ContractClass(typeof(IInterningProviderContract))] public interface IInterningProvider { diff --git a/ICSharpCode.NRefactory/TypeSystem/ISupportsInterning.cs b/ICSharpCode.NRefactory/TypeSystem/ISupportsInterning.cs index 2f3e312110..c937f605b9 100644 --- a/ICSharpCode.NRefactory/TypeSystem/ISupportsInterning.cs +++ b/ICSharpCode.NRefactory/TypeSystem/ISupportsInterning.cs @@ -9,6 +9,7 @@ namespace ICSharpCode.NRefactory.TypeSystem { /// /// Interface for DOM objects that support interning. + /// See for more information. /// [ContractClass(typeof(ISupportsInterningContract))] public interface ISupportsInterning