Browse Source

Cache resolved SimpleTypeOrNamespaceReference/MemberTypeOrNamespaceReference, and intern those references.

newNRvisualizers
Daniel Grunwald 15 years ago
parent
commit
391a6bc8b7
  1. 49
      ICSharpCode.NRefactory/CSharp/Parser/TypeSystemConvertVisitor.cs
  2. 51
      ICSharpCode.NRefactory/CSharp/Resolver/MemberTypeOrNamespaceReference.cs
  3. 2
      ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs
  4. 49
      ICSharpCode.NRefactory/CSharp/Resolver/SimpleTypeOrNamespaceReference.cs
  5. 1
      ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj
  6. 15
      ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleInterningProvider.cs
  7. 7
      ICSharpCode.NRefactory/Utils/CacheManager.cs
  8. 17
      ICSharpCode.NRefactory/Utils/FastSerializer.cs
  9. 39
      ICSharpCode.NRefactory/Utils/ReferenceComparer.cs

49
ICSharpCode.NRefactory/CSharp/Parser/TypeSystemConvertVisitor.cs

@ -39,6 +39,17 @@ namespace ICSharpCode.NRefactory.CSharp @@ -39,6 +39,17 @@ namespace ICSharpCode.NRefactory.CSharp
DefaultTypeDefinition currentTypeDefinition;
DefaultMethod currentMethod;
IInterningProvider interningProvider = new SimpleInterningProvider();
/// <summary>
/// Gets/Sets the interning provider to use.
/// The default value is a new <see cref="SimpleInterningProvider"/> instance.
/// </summary>
public IInterningProvider InterningProvider {
get { return interningProvider; }
set { interningProvider = value; }
}
/// <summary>
/// Creates a new TypeSystemConvertVisitor.
/// </summary>
@ -201,6 +212,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -201,6 +212,9 @@ namespace ICSharpCode.NRefactory.CSharp
td.HasExtensionMethods = td.Methods.Any(m => m.IsExtensionMethod);
currentTypeDefinition = (DefaultTypeDefinition)currentTypeDefinition.DeclaringTypeDefinition;
if (interningProvider != null) {
td.ApplyInterningProvider(interningProvider);
}
return td;
}
@ -231,6 +245,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -231,6 +245,9 @@ namespace ICSharpCode.NRefactory.CSharp
}
currentTypeDefinition = (DefaultTypeDefinition)currentTypeDefinition.DeclaringTypeDefinition;
if (interningProvider != null) {
td.ApplyInterningProvider(interningProvider);
}
return td;
}
@ -326,6 +343,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -326,6 +343,9 @@ namespace ICSharpCode.NRefactory.CSharp
}
currentTypeDefinition.Fields.Add(field);
if (interningProvider != null) {
field.ApplyInterningProvider(interningProvider);
}
}
return isSingleField ? field : null;
}
@ -351,6 +371,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -351,6 +371,9 @@ namespace ICSharpCode.NRefactory.CSharp
}
currentTypeDefinition.Fields.Add(field);
if (interningProvider != null) {
field.ApplyInterningProvider(interningProvider);
}
return field;
}
#endregion
@ -380,6 +403,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -380,6 +403,9 @@ namespace ICSharpCode.NRefactory.CSharp
currentTypeDefinition.Methods.Add(m);
currentMethod = null;
if (interningProvider != null) {
m.ApplyInterningProvider(interningProvider);
}
return m;
}
@ -443,6 +469,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -443,6 +469,9 @@ namespace ICSharpCode.NRefactory.CSharp
ConvertParameters(m.Parameters, operatorDeclaration.Parameters);
currentTypeDefinition.Methods.Add(m);
if (interningProvider != null) {
m.ApplyInterningProvider(interningProvider);
}
return m;
}
#endregion
@ -471,6 +500,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -471,6 +500,9 @@ namespace ICSharpCode.NRefactory.CSharp
ApplyModifiers(ctor, modifiers);
currentTypeDefinition.Methods.Add(ctor);
if (interningProvider != null) {
ctor.ApplyInterningProvider(interningProvider);
}
return ctor;
}
#endregion
@ -489,6 +521,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -489,6 +521,9 @@ namespace ICSharpCode.NRefactory.CSharp
ConvertAttributes(dtor.Attributes, destructorDeclaration.Attributes);
currentTypeDefinition.Methods.Add(dtor);
if (interningProvider != null) {
dtor.ApplyInterningProvider(interningProvider);
}
return dtor;
}
#endregion
@ -509,6 +544,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -509,6 +544,9 @@ namespace ICSharpCode.NRefactory.CSharp
p.Getter = ConvertAccessor(propertyDeclaration.Getter, p.Accessibility);
p.Setter = ConvertAccessor(propertyDeclaration.Setter, p.Accessibility);
currentTypeDefinition.Properties.Add(p);
if (interningProvider != null) {
p.ApplyInterningProvider(interningProvider);
}
return p;
}
@ -529,6 +567,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -529,6 +567,9 @@ namespace ICSharpCode.NRefactory.CSharp
p.Setter = ConvertAccessor(indexerDeclaration.Setter, p.Accessibility);
ConvertParameters(p.Parameters, indexerDeclaration.Parameters);
currentTypeDefinition.Properties.Add(p);
if (interningProvider != null) {
p.ApplyInterningProvider(interningProvider);
}
return p;
}
@ -582,6 +623,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -582,6 +623,9 @@ namespace ICSharpCode.NRefactory.CSharp
}
currentTypeDefinition.Events.Add(ev);
if (interningProvider != null) {
ev.ApplyInterningProvider(interningProvider);
}
}
return isSingleEvent ? ev : null;
}
@ -604,6 +648,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -604,6 +648,9 @@ namespace ICSharpCode.NRefactory.CSharp
e.RemoveAccessor = ConvertAccessor(eventDeclaration.RemoveAccessor, e.Accessibility);
currentTypeDefinition.Events.Add(e);
if (interningProvider != null) {
e.ApplyInterningProvider(interningProvider);
}
return e;
}
#endregion
@ -841,7 +888,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -841,7 +888,7 @@ namespace ICSharpCode.NRefactory.CSharp
}
internal static IConstantValue ConvertConstantValue(ITypeReference targetType, AstNode expression,
ITypeDefinition parentTypeDefinition, IMethod parentMethodDefinition, UsingScope parentUsingScope)
ITypeDefinition parentTypeDefinition, IMethod parentMethodDefinition, UsingScope parentUsingScope)
{
ConstantValueBuilder b = new ConstantValueBuilder(parentTypeDefinition, parentMethodDefinition, parentUsingScope, false);
ConstantExpression c = expression.AcceptVisitor(b, null);

51
ICSharpCode.NRefactory/CSharp/Resolver/MemberTypeOrNamespaceReference.cs

@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
using System;
using System.Collections.Generic;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.NRefactory.CSharp.Resolver
{
@ -26,13 +27,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -26,13 +27,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// Reference to a qualified type or namespace name.
/// </summary>
[Serializable]
public sealed class MemberTypeOrNamespaceReference : ITypeOrNamespaceReference
public sealed class MemberTypeOrNamespaceReference : ITypeOrNamespaceReference, ISupportsInterning
{
readonly ITypeOrNamespaceReference target;
ITypeOrNamespaceReference target;
readonly ITypeDefinition parentTypeDefinition;
readonly UsingScope parentUsingScope;
readonly string identifier;
readonly IList<ITypeReference> typeArguments;
string identifier;
IList<ITypeReference> typeArguments;
public MemberTypeOrNamespaceReference(ITypeOrNamespaceReference target, string identifier, IList<ITypeReference> typeArguments, ITypeDefinition parentTypeDefinition, UsingScope parentUsingScope)
{
@ -58,6 +59,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -58,6 +59,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public ResolveResult DoResolve(ITypeResolveContext context)
{
CacheManager cacheManager = context.CacheManager;
if (cacheManager != null) {
object result;
if (cacheManager.Dictionary.TryGetValue(this, out result))
return (ResolveResult)result;
}
ResolveResult targetRR = target.DoResolve(context);
if (targetRR.IsError)
return targetRR;
@ -68,7 +76,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -68,7 +76,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
for (int i = 0; i < typeArgs.Length; i++) {
typeArgs[i] = typeArguments[i].Resolve(context);
}
return r.ResolveMemberType(targetRR, identifier, typeArgs);
ResolveResult rr = r.ResolveMemberType(targetRR, identifier, typeArgs);
if (cacheManager != null)
cacheManager.Dictionary.TryAdd(this, rr);
return rr;
}
public NamespaceResolveResult ResolveNamespace(ITypeResolveContext context)
@ -91,5 +102,35 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -91,5 +102,35 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
else
return target.ToString() + "." + identifier + "<" + DotNet35Compat.StringJoin(",", typeArguments) + ">";
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
target = provider.Intern(target);
identifier = provider.Intern(identifier);
typeArguments = provider.InternList(typeArguments);
}
int ISupportsInterning.GetHashCodeForInterning()
{
int hashCode = 0;
unchecked {
hashCode += 1000000007 * target.GetHashCode();
if (parentTypeDefinition != null)
hashCode += 1000000009 * parentTypeDefinition.GetHashCode();
if (parentUsingScope != null)
hashCode += 1000000021 * parentUsingScope.GetHashCode();
hashCode += 1000000033 * identifier.GetHashCode();
hashCode += 1000000087 * typeArguments.GetHashCode();
}
return hashCode;
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
MemberTypeOrNamespaceReference o = other as MemberTypeOrNamespaceReference;
return o != null && this.target == o.target && this.parentTypeDefinition == o.parentTypeDefinition
&& this.parentUsingScope == o.parentUsingScope && this.identifier == o.identifier
&& this.typeArguments == o.typeArguments;
}
}
}

2
ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs

@ -1478,7 +1478,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1478,7 +1478,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
DomRegion MakeRegion(AstNode node)
{
return new DomRegion(parsedFile.FileName, node.StartLocation, node.EndLocation);
return new DomRegion(parsedFile != null ? parsedFile.FileName : null, node.StartLocation, node.EndLocation);
}
sealed class ExplicitlyTypedLambda : LambdaBase

49
ICSharpCode.NRefactory/CSharp/Resolver/SimpleTypeOrNamespaceReference.cs

@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
using System;
using System.Collections.Generic;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.NRefactory.CSharp.Resolver
{
@ -26,12 +27,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -26,12 +27,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// Represents a simple C# name. (a single non-qualified identifier with an optional list of type arguments)
/// </summary>
[Serializable]
public sealed class SimpleTypeOrNamespaceReference : ITypeOrNamespaceReference
public sealed class SimpleTypeOrNamespaceReference : ITypeOrNamespaceReference, ISupportsInterning
{
readonly ITypeDefinition parentTypeDefinition;
readonly UsingScope parentUsingScope;
readonly string identifier;
readonly IList<ITypeReference> typeArguments;
string identifier;
IList<ITypeReference> typeArguments;
readonly SimpleNameLookupMode lookupMode;
public SimpleTypeOrNamespaceReference(string identifier, IList<ITypeReference> typeArguments, ITypeDefinition parentTypeDefinition, UsingScope parentUsingScope, SimpleNameLookupMode lookupMode = SimpleNameLookupMode.Type)
@ -56,6 +57,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -56,6 +57,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public ResolveResult DoResolve(ITypeResolveContext context)
{
CacheManager cacheManager = context.CacheManager;
if (cacheManager != null) {
object result;
if (cacheManager.Dictionary.TryGetValue(this, out result))
return (ResolveResult)result;
}
CSharpResolver r = new CSharpResolver(context);
r.CurrentTypeDefinition = parentTypeDefinition;
r.UsingScope = parentUsingScope;
@ -63,7 +71,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -63,7 +71,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
for (int i = 0; i < typeArgs.Length; i++) {
typeArgs[i] = typeArguments[i].Resolve(context);
}
return r.LookupSimpleNameOrTypeName(identifier, typeArgs, lookupMode);
ResolveResult rr = r.LookupSimpleNameOrTypeName(identifier, typeArgs, lookupMode);
if (cacheManager != null)
cacheManager.Dictionary.TryAdd(this, rr);
return rr;
}
public NamespaceResolveResult ResolveNamespace(ITypeResolveContext context)
@ -86,5 +97,35 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -86,5 +97,35 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
else
return identifier + "<" + DotNet35Compat.StringJoin(",", typeArguments) + ">";
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
identifier = provider.Intern(identifier);
typeArguments = provider.InternList(typeArguments);
}
int ISupportsInterning.GetHashCodeForInterning()
{
int hashCode = 0;
unchecked {
if (parentTypeDefinition != null)
hashCode += 1000000007 * parentTypeDefinition.GetHashCode();
if (parentUsingScope != null)
hashCode += 1000000009 * parentUsingScope.GetHashCode();
hashCode += 1000000021 * identifier.GetHashCode();
hashCode += 1000000033 * typeArguments.GetHashCode();
hashCode += 1000000087 * (int)lookupMode;
}
return hashCode;
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
SimpleTypeOrNamespaceReference o = other as SimpleTypeOrNamespaceReference;
return o != null && this.parentTypeDefinition == o.parentTypeDefinition
&& this.parentUsingScope == o.parentUsingScope && this.identifier == o.identifier
&& this.typeArguments == o.typeArguments && this.lookupMode == o.lookupMode;
}
}
}

1
ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

@ -349,6 +349,7 @@ @@ -349,6 +349,7 @@
<Compile Include="Utils\FastSerializer.cs" />
<Compile Include="Utils\GraphVizGraph.cs" />
<Compile Include="Utils\Platform.cs" />
<Compile Include="Utils\ReferenceComparer.cs" />
<Compile Include="Utils\TreeTraversal.cs" />
<Compile Include="CSharp\Ast\ComposedType.cs" />
<Compile Include="CSharp\Ast\Expressions\DirectionExpression.cs" />

15
ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleInterningProvider.cs

@ -39,21 +39,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -39,21 +39,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
Intern(r);
}
sealed class ReferenceComparer : IEqualityComparer<object>
{
public readonly static ReferenceComparer Instance = new ReferenceComparer();
public new bool Equals(object a, object b)
{
return ReferenceEquals(a, b);
}
public int GetHashCode(object obj)
{
return RuntimeHelpers.GetHashCode(obj);
}
}
sealed class InterningComparer : IEqualityComparer<ISupportsInterning>
{
public bool Equals(ISupportsInterning x, ISupportsInterning y)

7
ICSharpCode.NRefactory/Utils/CacheManager.cs

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Concurrent;
using System.Threading;
namespace ICSharpCode.NRefactory.Utils
@ -28,6 +29,12 @@ namespace ICSharpCode.NRefactory.Utils @@ -28,6 +29,12 @@ namespace ICSharpCode.NRefactory.Utils
/// <remarks>This class is thread-safe</remarks>
public sealed class CacheManager : IDisposable
{
readonly ConcurrentDictionary<object, object> dict = new ConcurrentDictionary<object, object>(ReferenceComparer.Instance);
public ConcurrentDictionary<object, object> Dictionary {
get { return dict; }
}
/* Lots of code commented out because I don't know if it's useful, clients can usually replicate
* the functionality much more easily and only need the Disposed event to ensure cleanup.
*

17
ICSharpCode.NRefactory/Utils/FastSerializer.cs

@ -20,10 +20,8 @@ using System; @@ -20,10 +20,8 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
namespace ICSharpCode.NRefactory.Utils
@ -49,19 +47,6 @@ namespace ICSharpCode.NRefactory.Utils @@ -49,19 +47,6 @@ namespace ICSharpCode.NRefactory.Utils
#endregion
#region Serialization
sealed class ReferenceComparer : IEqualityComparer<object>
{
bool IEqualityComparer<object>.Equals(object a, object b)
{
return a == b;
}
int IEqualityComparer<object>.GetHashCode(object obj)
{
return RuntimeHelpers.GetHashCode(obj);
}
}
sealed class SerializationType
{
public readonly int ID;
@ -81,7 +66,7 @@ namespace ICSharpCode.NRefactory.Utils @@ -81,7 +66,7 @@ namespace ICSharpCode.NRefactory.Utils
sealed class SerializationContext
{
readonly Dictionary<object, int> objectToID = new Dictionary<object, int>(new ReferenceComparer());
readonly Dictionary<object, int> objectToID = new Dictionary<object, int>(ReferenceComparer.Instance);
readonly List<object> instances = new List<object>(); // index: object ID
readonly List<SerializationType> objectTypes = new List<SerializationType>(); // index: object ID
SerializationType stringType;

39
ICSharpCode.NRefactory/Utils/ReferenceComparer.cs

@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
// Copyright (c) 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.Generic;
using System.Runtime.CompilerServices;
namespace ICSharpCode.NRefactory.Utils
{
sealed class ReferenceComparer : IEqualityComparer<object>
{
public readonly static ReferenceComparer Instance = new ReferenceComparer();
public new bool Equals(object a, object b)
{
return ReferenceEquals(a, b);
}
public int GetHashCode(object obj)
{
return RuntimeHelpers.GetHashCode(obj);
}
}
}
Loading…
Cancel
Save