Browse Source

Change ISupportsInterning so that objects are interned immediately after they are created.

This lets us get rid of the hidden mutation due to interning; ISupportsInterning objects can now be truly immutable.
newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
79db6fe54c
  1. 6
      ICSharpCode.NRefactory.CSharp/Ast/AstType.cs
  2. 16
      ICSharpCode.NRefactory.CSharp/Ast/ComposedType.cs
  3. 14
      ICSharpCode.NRefactory.CSharp/Ast/MemberType.cs
  4. 2
      ICSharpCode.NRefactory.CSharp/Ast/PrimitiveType.cs
  5. 18
      ICSharpCode.NRefactory.CSharp/Ast/SimpleType.cs
  6. 6
      ICSharpCode.NRefactory.CSharp/Refactoring/TypeSystemAstBuilder.cs
  7. 4
      ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs
  8. 13
      ICSharpCode.NRefactory.CSharp/TypeSystem/AliasNamespaceReference.cs
  9. 8
      ICSharpCode.NRefactory.CSharp/TypeSystem/AttributeTypeReference.cs
  10. 92
      ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpAttribute.cs
  11. 253
      ICSharpCode.NRefactory.CSharp/TypeSystem/ConstantValues.cs
  12. 13
      ICSharpCode.NRefactory.CSharp/TypeSystem/MemberTypeOrNamespaceReference.cs
  13. 10
      ICSharpCode.NRefactory.CSharp/TypeSystem/SimpleTypeOrNamespaceReference.cs
  14. 233
      ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs
  15. 4
      ICSharpCode.NRefactory/Documentation/IdStringProvider.cs
  16. 9
      ICSharpCode.NRefactory/TypeSystem/ArrayType.cs
  17. 7
      ICSharpCode.NRefactory/TypeSystem/ByReferenceType.cs
  18. 207
      ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs
  19. 60
      ICSharpCode.NRefactory/TypeSystem/IInterningProvider.cs
  20. 5
      ICSharpCode.NRefactory/TypeSystem/ISupportsInterning.cs
  21. 2
      ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractResolvedTypeParameter.cs
  22. 10
      ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractUnresolvedEntity.cs
  23. 3
      ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractUnresolvedMember.cs
  24. 7
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAssemblyReference.cs
  25. 17
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultMemberReference.cs
  26. 68
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedAttribute.cs
  27. 8
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedEvent.cs
  28. 6
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedField.cs
  29. 2
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedMethod.cs
  30. 33
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedParameter.cs
  31. 4
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedProperty.cs
  32. 16
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedTypeParameter.cs
  33. 2
      ICSharpCode.NRefactory/TypeSystem/Implementation/DummyTypeParameter.cs
  34. 13
      ICSharpCode.NRefactory/TypeSystem/Implementation/GetClassTypeReference.cs
  35. 12
      ICSharpCode.NRefactory/TypeSystem/Implementation/NestedTypeReference.cs
  36. 10
      ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleConstantValue.cs
  37. 76
      ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleInterningProvider.cs
  38. 39
      ICSharpCode.NRefactory/TypeSystem/Implementation/TypeParameterReference.cs
  39. 2
      ICSharpCode.NRefactory/TypeSystem/NullableType.cs
  40. 12
      ICSharpCode.NRefactory/TypeSystem/ParameterizedType.cs
  41. 7
      ICSharpCode.NRefactory/TypeSystem/PointerType.cs
  42. 8
      ICSharpCode.NRefactory/TypeSystem/ReflectionHelper.cs

6
ICSharpCode.NRefactory.CSharp/Ast/AstType.cs

@ -58,7 +58,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -58,7 +58,7 @@ namespace ICSharpCode.NRefactory.CSharp
return other == null || other.IsNull;
}
public override ITypeReference ToTypeReference(NameLookupMode lookupMode)
public override ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider)
{
return SpecialType.UnknownType;
}
@ -99,7 +99,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -99,7 +99,7 @@ namespace ICSharpCode.NRefactory.CSharp
return visitor.VisitPatternPlaceholder (this, child, data);
}
public override ITypeReference ToTypeReference(NameLookupMode lookupMode)
public override ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider)
{
throw new NotSupportedException();
}
@ -135,7 +135,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -135,7 +135,7 @@ namespace ICSharpCode.NRefactory.CSharp
/// For resolving simple names, the current namespace and usings from the CurrentUsingScope
/// (on CSharpTypeResolveContext only) is used.
/// </remarks>
public abstract ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type);
public abstract ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type, InterningProvider interningProvider = null);
/// <summary>
/// Creates a pointer type from this type by nesting it in a <see cref="ComposedType"/>.

16
ICSharpCode.NRefactory.CSharp/Ast/ComposedType.cs

@ -78,7 +78,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -78,7 +78,7 @@ namespace ICSharpCode.NRefactory.CSharp
{
visitor.VisitComposedType (this);
}
public override T AcceptVisitor<T> (IAstVisitor<T> visitor)
{
return visitor.VisitComposedType (this);
@ -126,18 +126,20 @@ namespace ICSharpCode.NRefactory.CSharp @@ -126,18 +126,20 @@ namespace ICSharpCode.NRefactory.CSharp
return this;
}
public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type)
public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type, InterningProvider interningProvider = null)
{
ITypeReference t = this.BaseType.ToTypeReference(lookupMode);
if (interningProvider == null)
interningProvider = InterningProvider.Dummy;
ITypeReference t = this.BaseType.ToTypeReference(lookupMode, interningProvider);
if (this.HasNullableSpecifier) {
t = NullableType.Create(t);
t = interningProvider.Intern(NullableType.Create(t));
}
int pointerRank = this.PointerRank;
for (int i = 0; i < pointerRank; i++) {
t = new PointerTypeReference(t);
t = interningProvider.Intern(new PointerTypeReference(t));
}
foreach (var a in this.ArraySpecifiers.Reverse()) {
t = new ArrayTypeReference(t, a.Dimensions);
t = interningProvider.Intern(new ArrayTypeReference(t, a.Dimensions));
}
return t;
}
@ -190,7 +192,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -190,7 +192,7 @@ namespace ICSharpCode.NRefactory.CSharp
{
visitor.VisitArraySpecifier (this);
}
public override T AcceptVisitor<T> (IAstVisitor<T> visitor)
{
return visitor.VisitArraySpecifier (this);

14
ICSharpCode.NRefactory.CSharp/Ast/MemberType.cs

@ -135,26 +135,30 @@ namespace ICSharpCode.NRefactory.CSharp @@ -135,26 +135,30 @@ namespace ICSharpCode.NRefactory.CSharp
return b.ToString();
}
public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type)
public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type, InterningProvider interningProvider = null)
{
if (interningProvider == null)
interningProvider = InterningProvider.Dummy;
TypeOrNamespaceReference t;
if (this.IsDoubleColon) {
SimpleType st = this.Target as SimpleType;
if (st != null) {
t = new AliasNamespaceReference(st.Identifier);
t = interningProvider.Intern(new AliasNamespaceReference(interningProvider.Intern(st.Identifier)));
} else {
t = null;
}
} else {
t = this.Target.ToTypeReference(lookupMode) as TypeOrNamespaceReference;
t = this.Target.ToTypeReference(lookupMode, interningProvider) as TypeOrNamespaceReference;
}
if (t == null)
return SpecialType.UnknownType;
var typeArguments = new List<ITypeReference>();
foreach (var ta in this.TypeArguments) {
typeArguments.Add(ta.ToTypeReference(lookupMode));
typeArguments.Add(ta.ToTypeReference(lookupMode, interningProvider));
}
return new MemberTypeOrNamespaceReference(t, this.MemberName, typeArguments, lookupMode);
string memberName = interningProvider.Intern(this.MemberName);
return interningProvider.Intern(new MemberTypeOrNamespaceReference(t, memberName, interningProvider.InternList(typeArguments), lookupMode));
}
}
}

2
ICSharpCode.NRefactory.CSharp/Ast/PrimitiveType.cs

@ -103,7 +103,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -103,7 +103,7 @@ namespace ICSharpCode.NRefactory.CSharp
return Keyword;
}
public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type)
public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type, InterningProvider interningProvider = null)
{
KnownTypeCode typeCode = GetTypeCodeForPrimitiveType(this.Keyword);
if (typeCode == KnownTypeCode.None)

18
ICSharpCode.NRefactory.CSharp/Ast/SimpleType.cs

@ -50,7 +50,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -50,7 +50,7 @@ namespace ICSharpCode.NRefactory.CSharp
public override void AcceptVisitor (IAstVisitor visitor)
{
}
public override T AcceptVisitor<T> (IAstVisitor<T> visitor)
{
return default (T);
@ -66,7 +66,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -66,7 +66,7 @@ namespace ICSharpCode.NRefactory.CSharp
return other == null || other.IsNull;
}
public override ITypeReference ToTypeReference(NameLookupMode lookupMode)
public override ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider)
{
return SpecialType.UnknownType;
}
@ -130,7 +130,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -130,7 +130,7 @@ namespace ICSharpCode.NRefactory.CSharp
{
visitor.VisitSimpleType (this);
}
public override T AcceptVisitor<T> (IAstVisitor<T> visitor)
{
return visitor.VisitSimpleType (this);
@ -158,17 +158,21 @@ namespace ICSharpCode.NRefactory.CSharp @@ -158,17 +158,21 @@ namespace ICSharpCode.NRefactory.CSharp
return b.ToString();
}
public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type)
public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type, InterningProvider interningProvider = null)
{
if (interningProvider == null)
interningProvider = InterningProvider.Dummy;
var typeArguments = new List<ITypeReference>();
foreach (var ta in this.TypeArguments) {
typeArguments.Add(ta.ToTypeReference(lookupMode));
typeArguments.Add(ta.ToTypeReference(lookupMode, interningProvider));
}
if (typeArguments.Count == 0 && string.IsNullOrEmpty(this.Identifier)) {
string identifier = interningProvider.Intern(this.Identifier);
if (typeArguments.Count == 0 && string.IsNullOrEmpty(identifier)) {
// empty SimpleType is used for typeof(List<>).
return SpecialType.UnboundTypeArgument;
}
return new SimpleTypeOrNamespaceReference(this.Identifier, typeArguments, lookupMode);
var t = new SimpleTypeOrNamespaceReference(identifier, interningProvider.InternList(typeArguments), lookupMode);
return interningProvider.Intern(t);
}
}
}

6
ICSharpCode.NRefactory.CSharp/Refactoring/TypeSystemAstBuilder.cs

@ -285,16 +285,18 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -285,16 +285,18 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
/// Adds type arguments to the result type.
/// </summary>
/// <param name="result">The result AST node (a SimpleType or MemberType)</param>
/// <param name="typeDef">The type definition that owns the type parameters</param>
/// <param name="typeArguments">The list of type arguments</param>
/// <param name="startIndex">Index of first type argument to add</param>
/// <param name="endIndex">Index after last type argument to add</param>
void AddTypeArguments(AstType result, ITypeDefinition typeDef, IList<IType> typeArguments, int startIndex, int endIndex)
{
Debug.Assert(endIndex <= typeDef.TypeParameterCount);
for (int i = startIndex; i < endIndex; i++) {
if (ConvertUnboundTypeArguments && typeArguments[i].Kind == TypeKind.UnboundTypeArgument) {
result.AddChild(new SimpleType(typeDef.TypeParameters [i].Name), Roles.TypeArgument);
result.AddChild(new SimpleType(typeDef.TypeParameters[i].Name), Roles.TypeArgument);
} else {
result.AddChild(ConvertType(typeArguments [i]), Roles.TypeArgument);
result.AddChild(ConvertType(typeArguments[i]), Roles.TypeArgument);
}
}
}

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

@ -797,7 +797,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -797,7 +797,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} else {
// Re-discover the method:
EntityType entityType = memberDeclaration.EntityType;
var parameterTypes = TypeSystemConvertVisitor.GetParameterTypes(memberDeclaration.GetChildrenByRole(Roles.Parameter));
var parameterTypes = TypeSystemConvertVisitor.GetParameterTypes(memberDeclaration.GetChildrenByRole(Roles.Parameter), InterningProvider.Dummy);
if (entityType == EntityType.Constructor) {
string name = memberDeclaration.HasModifier(Modifiers.Static) ? ".cctor" : ".ctor";
member = AbstractUnresolvedMember.Resolve(
@ -860,7 +860,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -860,7 +860,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} else {
// Re-discover the property:
string name = propertyOrIndexerDeclaration.Name;
var parameterTypeReferences = TypeSystemConvertVisitor.GetParameterTypes(propertyOrIndexerDeclaration.GetChildrenByRole(Roles.Parameter));
var parameterTypeReferences = TypeSystemConvertVisitor.GetParameterTypes(propertyOrIndexerDeclaration.GetChildrenByRole(Roles.Parameter), InterningProvider.Dummy);
AstType explicitInterfaceAstType = propertyOrIndexerDeclaration.GetChildByRole(EntityDeclaration.PrivateImplementationTypeRole);
ITypeReference explicitInterfaceType = null;
if (!explicitInterfaceAstType.IsNull) {

13
ICSharpCode.NRefactory.CSharp/TypeSystem/AliasNamespaceReference.cs

@ -31,7 +31,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -31,7 +31,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
/// by <see cref="MemberTypeOrNamespaceReference"/>.
/// </remarks>
[Serializable]
public class AliasNamespaceReference : TypeOrNamespaceReference
public sealed class AliasNamespaceReference : TypeOrNamespaceReference, ISupportsInterning
{
readonly string identifier;
@ -55,5 +55,16 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -55,5 +55,16 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
{
return identifier + "::";
}
int ISupportsInterning.GetHashCodeForInterning()
{
return identifier.GetHashCode();
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
AliasNamespaceReference anr = other as AliasNamespaceReference;
return anr != null && this.identifier == anr.identifier;
}
}
}

8
ICSharpCode.NRefactory.CSharp/TypeSystem/AttributeTypeReference.cs

@ -35,7 +35,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -35,7 +35,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
[Serializable]
public sealed class AttributeTypeReference : ITypeReference, ISupportsInterning
{
ITypeReference withoutSuffix, withSuffix;
readonly ITypeReference withoutSuffix, withSuffix;
public AttributeTypeReference(ITypeReference withoutSuffix, ITypeReference withSuffix)
{
@ -75,12 +75,6 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -75,12 +75,6 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
return withoutSuffix.ToString() + "[Attribute]";
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
withoutSuffix = provider.Intern(withoutSuffix);
withSuffix = provider.Intern(withSuffix);
}
int ISupportsInterning.GetHashCodeForInterning()
{
unchecked {

92
ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpAttribute.cs

@ -51,7 +51,8 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -51,7 +51,8 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
this.namedCtorArguments = namedCtorArguments ?? EmptyList<KeyValuePair<string, IConstantValue>>.Instance;
this.namedArguments = namedArguments ?? EmptyList<KeyValuePair<string, IConstantValue>>.Instance;
}
public DomRegion Region {
public DomRegion Region {
get { return region; }
}
@ -165,93 +166,4 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -165,93 +166,4 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
}
}
}
/*
public IMethod ResolveConstructor(ITypeResolveContext context)
{
CSharpResolver r = new CSharpResolver(context);
IType type = attributeType.Resolve(context);
int totalArgumentCount = 0;
if (positionalArguments != null)
totalArgumentCount += positionalArguments.Count;
if (namedCtorArguments != null)
totalArgumentCount += namedCtorArguments.Count;
ResolveResult[] arguments = new ResolveResult[totalArgumentCount];
string[] argumentNames = new string[totalArgumentCount];
int i = 0;
if (positionalArguments != null) {
while (i < positionalArguments.Count) {
IConstantValue cv = positionalArguments[i];
arguments[i] = cv.Resolve(context);
i++;
}
}
if (namedCtorArguments != null) {
foreach (var pair in namedCtorArguments) {
argumentNames[i] = pair.Key;
arguments[i] = pair.Value.Resolve(context);
i++;
}
}
MemberResolveResult mrr = r.ResolveObjectCreation(type, arguments, argumentNames) as MemberResolveResult;
return mrr != null ? mrr.Member as IMethod : null;
}
public IList<ResolveResult> GetPositionalArguments(ITypeResolveContext context)
{
List<ResolveResult> result = new List<ResolveResult>();
if (positionalArguments != null) {
foreach (var arg in positionalArguments) {
result.Add(Resolve(arg, context));
}
}
if (namedCtorArguments == null || namedCtorArguments.Count == 0) {
// no namedCtorArguments: just return the positionalArguments
return result.AsReadOnly();
}
// we do have namedCtorArguments, which need to be re-ordered and appended to the positional arguments
IMethod method = ResolveConstructor(context);
if (method != null) {
for (int i = result.Count; i < method.Parameters.Count; i++) {
IParameter p = method.Parameters[i];
bool found = false;
foreach (var pair in namedCtorArguments) {
if (pair.Key == p.Name) {
result.Add(Resolve(pair.Value, context));
found = true;
}
}
if (!found) {
// add the parameter's default value:
if (p.DefaultValue != null) {
result.Add(Resolve(p.DefaultValue, context));
} else {
IType type = p.Type.Resolve(context);
result.Add(new ConstantResolveResult(type, CSharpResolver.GetDefaultValue(type)));
}
}
}
}
return result.AsReadOnly();
}
ResolveResult Resolve(IConstantValue constantValue, ITypeResolveContext context)
{
if (constantValue != null)
return constantValue.Resolve(context);
else
return new ErrorResolveResult(SpecialType.UnknownType);
}
public IList<KeyValuePair<string, ResolveResult>> GetNamedArguments(ITypeResolveContext context)
{
if (namedArguments != null) {
return namedArguments.Select(p => new KeyValuePair<string, ResolveResult>(p.Key, p.Value.Resolve(context)))
.ToList().AsReadOnly();
} else {
return EmptyList<KeyValuePair<string, ResolveResult>>.Instance;
}
}
}
*/
}

253
ICSharpCode.NRefactory.CSharp/TypeSystem/ConstantValues.cs

@ -128,8 +128,8 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues @@ -128,8 +128,8 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
[Serializable]
public sealed class IncrementConstantValue : IConstantValue, ISupportsInterning
{
IConstantValue baseValue;
int incrementAmount;
readonly IConstantValue baseValue;
readonly int incrementAmount;
public IncrementConstantValue(IConstantValue baseValue, int incrementAmount = 1)
{
@ -160,11 +160,6 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues @@ -160,11 +160,6 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
return new ErrorResolveResult(rr.Type);
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
baseValue = provider.Intern(baseValue);
}
int ISupportsInterning.GetHashCodeForInterning()
{
unchecked {
@ -185,8 +180,8 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues @@ -185,8 +180,8 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
[Serializable]
public sealed class PrimitiveConstantExpression : ConstantExpression, ISupportsInterning
{
ITypeReference type;
object value;
readonly ITypeReference type;
readonly object value;
public ITypeReference Type {
get { return type; }
@ -209,12 +204,6 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues @@ -209,12 +204,6 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
return new ConstantResolveResult(type.Resolve(resolver.CurrentTypeResolveContext), value);
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
type = provider.Intern(type);
value = provider.Intern(value);
}
int ISupportsInterning.GetHashCodeForInterning()
{
return type.GetHashCode() ^ (value != null ? value.GetHashCode() : 0);
@ -228,9 +217,9 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues @@ -228,9 +217,9 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
}
[Serializable]
public sealed class TypeOfConstantExpression : ConstantExpression, ISupportsInterning
public sealed class TypeOfConstantExpression : ConstantExpression
{
ITypeReference type;
readonly ITypeReference type;
public ITypeReference Type {
get { return type; }
@ -245,29 +234,13 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues @@ -245,29 +234,13 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
{
return resolver.ResolveTypeOf(type.Resolve(resolver.CurrentTypeResolveContext));
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
type = provider.Intern(type);
}
int ISupportsInterning.GetHashCodeForInterning()
{
return type.GetHashCode();
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
TypeOfConstantExpression o = other as TypeOfConstantExpression;
return o != null && type == o.type;
}
}
[Serializable]
public sealed class ConstantCast : ConstantExpression, ISupportsInterning
{
ITypeReference targetType;
ConstantExpression expression;
readonly ITypeReference targetType;
readonly ConstantExpression expression;
public ConstantCast(ITypeReference targetType, ConstantExpression expression)
{
@ -284,12 +257,6 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues @@ -284,12 +257,6 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
return resolver.ResolveCast(targetType.Resolve(resolver.CurrentTypeResolveContext), expression.Resolve(resolver));
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
targetType = provider.Intern(targetType);
expression = provider.Intern(expression);
}
int ISupportsInterning.GetHashCodeForInterning()
{
unchecked {
@ -306,10 +273,10 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues @@ -306,10 +273,10 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
}
[Serializable]
public sealed class ConstantIdentifierReference : ConstantExpression, ISupportsInterning
public sealed class ConstantIdentifierReference : ConstantExpression
{
string identifier;
IList<ITypeReference> typeArguments;
readonly string identifier;
readonly IList<ITypeReference> typeArguments;
public ConstantIdentifierReference(string identifier, IList<ITypeReference> typeArguments = null)
{
@ -323,35 +290,15 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues @@ -323,35 +290,15 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
{
return resolver.ResolveSimpleName(identifier, typeArguments.Resolve(resolver.CurrentTypeResolveContext));
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
identifier = provider.Intern(identifier);
typeArguments = provider.InternList(typeArguments);
}
int ISupportsInterning.GetHashCodeForInterning()
{
unchecked {
return identifier.GetHashCode() ^ typeArguments.GetHashCode();
}
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
ConstantIdentifierReference cir = other as ConstantIdentifierReference;
return cir != null &&
this.identifier == cir.identifier && this.typeArguments == cir.typeArguments;
}
}
[Serializable]
public sealed class ConstantMemberReference : ConstantExpression, ISupportsInterning
public sealed class ConstantMemberReference : ConstantExpression
{
ITypeReference targetType;
ConstantExpression targetExpression;
string memberName;
IList<ITypeReference> typeArguments;
readonly ITypeReference targetType;
readonly ConstantExpression targetExpression;
readonly string memberName;
readonly IList<ITypeReference> typeArguments;
public ConstantMemberReference(ITypeReference targetType, string memberName, IList<ITypeReference> typeArguments = null)
{
@ -384,43 +331,13 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues @@ -384,43 +331,13 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
rr = targetExpression.Resolve(resolver);
return resolver.ResolveMemberAccess(rr, memberName, typeArguments.Resolve(resolver.CurrentTypeResolveContext));
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
targetType = provider.Intern(targetType);
targetExpression = provider.Intern(targetExpression);
memberName = provider.Intern(memberName);
typeArguments = provider.InternList(typeArguments);
}
int ISupportsInterning.GetHashCodeForInterning()
{
unchecked {
int hashCode;
if (targetType != null)
hashCode = targetType.GetHashCode();
else
hashCode = targetExpression.GetHashCode();
hashCode ^= memberName.GetHashCode();
hashCode ^= typeArguments.GetHashCode();
return hashCode;
}
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
ConstantMemberReference cmr = other as ConstantMemberReference;
return cmr != null
&& this.targetType == cmr.targetType && this.targetExpression == cmr.targetExpression
&& this.memberName == cmr.memberName && this.typeArguments == cmr.typeArguments;
}
}
[Serializable]
public sealed class ConstantCheckedExpression : ConstantExpression, ISupportsInterning
public sealed class ConstantCheckedExpression : ConstantExpression
{
bool checkForOverflow;
ConstantExpression expression;
readonly bool checkForOverflow;
readonly ConstantExpression expression;
public ConstantCheckedExpression(bool checkForOverflow, ConstantExpression expression)
{
@ -434,30 +351,12 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues @@ -434,30 +351,12 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
{
return expression.Resolve(resolver.WithCheckForOverflow(checkForOverflow));
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
expression = provider.Intern(expression);
}
int ISupportsInterning.GetHashCodeForInterning()
{
return expression.GetHashCode() ^ (checkForOverflow ? 161851612 : 75163517);
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
ConstantCheckedExpression cce = other as ConstantCheckedExpression;
return cce != null
&& this.expression == cce.expression
&& this.checkForOverflow == cce.checkForOverflow;
}
}
[Serializable]
public sealed class ConstantDefaultValue : ConstantExpression, ISupportsInterning
{
ITypeReference type;
readonly ITypeReference type;
public ConstantDefaultValue(ITypeReference type)
{
@ -471,11 +370,6 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues @@ -471,11 +370,6 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
return resolver.ResolveDefaultValue(type.Resolve(resolver.CurrentTypeResolveContext));
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
type = provider.Intern(type);
}
int ISupportsInterning.GetHashCodeForInterning()
{
return type.GetHashCode();
@ -489,10 +383,10 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues @@ -489,10 +383,10 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
}
[Serializable]
public sealed class ConstantUnaryOperator : ConstantExpression, ISupportsInterning
public sealed class ConstantUnaryOperator : ConstantExpression
{
UnaryOperatorType operatorType;
ConstantExpression expression;
readonly UnaryOperatorType operatorType;
readonly ConstantExpression expression;
public ConstantUnaryOperator(UnaryOperatorType operatorType, ConstantExpression expression)
{
@ -506,34 +400,14 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues @@ -506,34 +400,14 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
{
return resolver.ResolveUnaryOperator(operatorType, expression.Resolve(resolver));
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
expression = provider.Intern(expression);
}
int ISupportsInterning.GetHashCodeForInterning()
{
unchecked {
return expression.GetHashCode() * 811 + operatorType.GetHashCode();
}
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
ConstantUnaryOperator uop = other as ConstantUnaryOperator;
return uop != null
&& this.operatorType == uop.operatorType
&& this.expression == uop.expression;
}
}
[Serializable]
public sealed class ConstantBinaryOperator : ConstantExpression, ISupportsInterning
public sealed class ConstantBinaryOperator : ConstantExpression
{
ConstantExpression left;
BinaryOperatorType operatorType;
ConstantExpression right;
readonly ConstantExpression left;
readonly BinaryOperatorType operatorType;
readonly ConstantExpression right;
public ConstantBinaryOperator(ConstantExpression left, BinaryOperatorType operatorType, ConstantExpression right)
{
@ -552,33 +426,12 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues @@ -552,33 +426,12 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
ResolveResult rhs = right.Resolve(resolver);
return resolver.ResolveBinaryOperator(operatorType, lhs, rhs);
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
left = provider.Intern(left);
right = provider.Intern(right);
}
int ISupportsInterning.GetHashCodeForInterning()
{
unchecked {
return left.GetHashCode() * 811 + operatorType.GetHashCode() + right.GetHashCode() * 91781;
}
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
ConstantBinaryOperator bop = other as ConstantBinaryOperator;
return bop != null
&& this.operatorType == bop.operatorType
&& this.left == bop.left && this.right == bop.right;
}
}
[Serializable]
public sealed class ConstantConditionalOperator : ConstantExpression, ISupportsInterning
public sealed class ConstantConditionalOperator : ConstantExpression
{
ConstantExpression condition, trueExpr, falseExpr;
readonly ConstantExpression condition, trueExpr, falseExpr;
public ConstantConditionalOperator(ConstantExpression condition, ConstantExpression trueExpr, ConstantExpression falseExpr)
{
@ -601,42 +454,17 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues @@ -601,42 +454,17 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
falseExpr.Resolve(resolver)
);
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
condition = provider.Intern(condition);
trueExpr = provider.Intern(trueExpr);
falseExpr = provider.Intern(falseExpr);
}
int ISupportsInterning.GetHashCodeForInterning()
{
unchecked {
return condition.GetHashCode() * 182981713
+ trueExpr.GetHashCode() * 917517169
+ falseExpr.GetHashCode() * 611651;
}
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
ConstantConditionalOperator coo = other as ConstantConditionalOperator;
return coo != null
&& this.condition == coo.condition
&& this.trueExpr == coo.trueExpr
&& this.falseExpr == coo.falseExpr;
}
}
/// <summary>
/// Represents an array creation (as used within an attribute argument)
/// </summary>
[Serializable]
public sealed class ConstantArrayCreation : ConstantExpression, ISupportsInterning
public sealed class ConstantArrayCreation : ConstantExpression
{
// type may be null when the element is being inferred
ITypeReference elementType;
IList<ConstantExpression> arrayElements;
readonly ITypeReference elementType;
readonly IList<ConstantExpression> arrayElements;
public ConstantArrayCreation(ITypeReference type, IList<ConstantExpression> arrayElements)
{
@ -658,22 +486,5 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues @@ -658,22 +486,5 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
return resolver.ResolveArrayCreation(null, 1, null, elements);
}
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
elementType = provider.Intern(elementType);
arrayElements = provider.InternList(arrayElements);
}
int ISupportsInterning.GetHashCodeForInterning()
{
return (elementType != null ? elementType.GetHashCode() : 0) ^ arrayElements.GetHashCode();
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
ConstantArrayCreation cac = other as ConstantArrayCreation;
return cac != null && this.elementType == cac.elementType && this.arrayElements == cac.arrayElements;
}
}
}

13
ICSharpCode.NRefactory.CSharp/TypeSystem/MemberTypeOrNamespaceReference.cs

@ -32,9 +32,9 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -32,9 +32,9 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
[Serializable]
public sealed class MemberTypeOrNamespaceReference : TypeOrNamespaceReference, ISupportsInterning
{
TypeOrNamespaceReference target;
string identifier;
IList<ITypeReference> typeArguments;
readonly TypeOrNamespaceReference target;
readonly string identifier;
readonly IList<ITypeReference> typeArguments;
readonly NameLookupMode lookupMode;
public MemberTypeOrNamespaceReference(TypeOrNamespaceReference target, string identifier, IList<ITypeReference> typeArguments, NameLookupMode lookupMode = NameLookupMode.Type)
@ -94,13 +94,6 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -94,13 +94,6 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
return target.ToString() + "." + identifier + "<" + string.Join(",", typeArguments) + ">";
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
target = provider.Intern(target);
identifier = provider.Intern(identifier);
typeArguments = provider.InternList(typeArguments);
}
int ISupportsInterning.GetHashCodeForInterning()
{
int hashCode = 0;

10
ICSharpCode.NRefactory.CSharp/TypeSystem/SimpleTypeOrNamespaceReference.cs

@ -33,8 +33,8 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -33,8 +33,8 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
[Serializable]
public sealed class SimpleTypeOrNamespaceReference : TypeOrNamespaceReference, ISupportsInterning
{
string identifier;
IList<ITypeReference> typeArguments;
readonly string identifier;
readonly IList<ITypeReference> typeArguments;
readonly NameLookupMode lookupMode;
public SimpleTypeOrNamespaceReference(string identifier, IList<ITypeReference> typeArguments, NameLookupMode lookupMode = NameLookupMode.Type)
@ -77,12 +77,6 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -77,12 +77,6 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
return identifier + "<" + string.Join(",", typeArguments) + ">";
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
identifier = provider.Intern(identifier);
typeArguments = provider.InternList(typeArguments);
}
int ISupportsInterning.GetHashCodeForInterning()
{
int hashCode = 0;

233
ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs

@ -46,15 +46,19 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -46,15 +46,19 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
CSharpUnresolvedTypeDefinition currentTypeDefinition;
DefaultUnresolvedMethod currentMethod;
IInterningProvider interningProvider = new SimpleInterningProvider();
InterningProvider 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 {
public InterningProvider InterningProvider {
get { return interningProvider; }
set { interningProvider = value; }
set {
if (interningProvider == null)
throw new ArgumentNullException();
interningProvider = value;
}
}
/// <summary>
@ -143,10 +147,8 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -143,10 +147,8 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
public override IUnresolvedEntity VisitUsingDeclaration(UsingDeclaration usingDeclaration)
{
TypeOrNamespaceReference u = usingDeclaration.Import.ToTypeReference(NameLookupMode.TypeInUsingDeclaration) as TypeOrNamespaceReference;
var u = ConvertTypeReference(usingDeclaration.Import, NameLookupMode.TypeInUsingDeclaration) as TypeOrNamespaceReference;
if (u != null) {
if (interningProvider != null)
u = interningProvider.Intern(u);
usingScope.Usings.Add(u);
}
return null;
@ -154,10 +156,8 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -154,10 +156,8 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
public override IUnresolvedEntity VisitUsingAliasDeclaration(UsingAliasDeclaration usingDeclaration)
{
TypeOrNamespaceReference u = usingDeclaration.Import.ToTypeReference(NameLookupMode.TypeInUsingDeclaration) as TypeOrNamespaceReference;
TypeOrNamespaceReference u = ConvertTypeReference(usingDeclaration.Import, NameLookupMode.TypeInUsingDeclaration) as TypeOrNamespaceReference;
if (u != null) {
if (interningProvider != null)
u = interningProvider.Intern(u);
usingScope.UsingAliases.Add(new KeyValuePair<string, TypeOrNamespaceReference>(usingDeclaration.Alias, u));
}
return null;
@ -225,7 +225,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -225,7 +225,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
ConvertTypeParameters(td.TypeParameters, typeDeclaration.TypeParameters, typeDeclaration.Constraints, EntityType.TypeDefinition);
foreach (AstType baseType in typeDeclaration.BaseTypes) {
td.BaseTypes.Add(baseType.ToTypeReference(NameLookupMode.BaseTypeReference));
td.BaseTypes.Add(ConvertTypeReference(baseType, NameLookupMode.BaseTypeReference));
}
foreach (EntityDeclaration member in typeDeclaration.Members) {
@ -233,9 +233,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -233,9 +233,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
}
currentTypeDefinition = (CSharpUnresolvedTypeDefinition)currentTypeDefinition.DeclaringTypeDefinition;
if (interningProvider != null) {
td.ApplyInterningProvider(interningProvider);
}
td.ApplyInterningProvider(interningProvider);
return td;
}
@ -252,7 +250,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -252,7 +250,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
ConvertTypeParameters(td.TypeParameters, delegateDeclaration.TypeParameters, delegateDeclaration.Constraints, EntityType.TypeDefinition);
ITypeReference returnType = delegateDeclaration.ReturnType.ToTypeReference();
ITypeReference returnType = ConvertTypeReference(delegateDeclaration.ReturnType);
List<IUnresolvedParameter> parameters = new List<IUnresolvedParameter>();
ConvertParameters(parameters, delegateDeclaration.Parameters);
AddDefaultMethodsToDelegate(td, returnType, parameters);
@ -273,9 +271,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -273,9 +271,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
}
currentTypeDefinition = (CSharpUnresolvedTypeDefinition)currentTypeDefinition.DeclaringTypeDefinition;
if (interningProvider != null) {
td.ApplyInterningProvider(interningProvider);
}
td.ApplyInterningProvider(interningProvider);
return td;
}
@ -364,7 +360,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -364,7 +360,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
field.IsVolatile = (modifiers & Modifiers.Volatile) != 0;
field.IsReadOnly = (modifiers & Modifiers.Readonly) != 0;
field.ReturnType = fieldDeclaration.ReturnType.ToTypeReference();
field.ReturnType = ConvertTypeReference(fieldDeclaration.ReturnType);
if ((modifiers & Modifiers.Const) != 0) {
field.ConstantValue = ConvertConstantValue(field.ReturnType, vi.Initializer);
@ -372,9 +368,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -372,9 +368,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
}
currentTypeDefinition.Members.Add(field);
if (interningProvider != null) {
field.ApplyInterningProvider(interningProvider);
}
field.ApplyInterningProvider(interningProvider);
}
return isSingleField ? field : null;
}
@ -397,9 +391,9 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -397,9 +391,9 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
} else {
ITypeReference[] typeArgs = new ITypeReference[currentTypeDefinition.TypeParameters.Count];
for (int i = 0; i < typeArgs.Length; i++) {
typeArgs[i] = new TypeParameterReference(EntityType.TypeDefinition, i);
typeArgs[i] = TypeParameterReference.Create(EntityType.TypeDefinition, i);
}
field.ReturnType = new ParameterizedTypeReference(currentTypeDefinition, typeArgs);
field.ReturnType = interningProvider.Intern(new ParameterizedTypeReference(currentTypeDefinition, typeArgs));
}
field.Accessibility = Accessibility.Public;
field.IsStatic = true;
@ -410,14 +404,12 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -410,14 +404,12 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
if (prevField == null || prevField.ConstantValue == null) {
field.ConstantValue = ConvertConstantValue(field.ReturnType, new PrimitiveExpression(0));
} else {
field.ConstantValue = new IncrementConstantValue(prevField.ConstantValue);
field.ConstantValue = interningProvider.Intern(new IncrementConstantValue(prevField.ConstantValue));
}
}
currentTypeDefinition.Members.Add(field);
if (interningProvider != null) {
field.ApplyInterningProvider(interningProvider);
}
field.ApplyInterningProvider(interningProvider);
return field;
}
#endregion
@ -438,12 +430,13 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -438,12 +430,13 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
tp.Region = MakeRegion(tpDecl);
ConvertAttributes(tp.Attributes, tpDecl.Attributes);
tp.Variance = tpDecl.Variance;
tp.ApplyInterningProvider(interningProvider);
m.TypeParameters.Add(tp);
}
} else {
ConvertTypeParameters(m.TypeParameters, methodDeclaration.TypeParameters, methodDeclaration.Constraints, EntityType.Method);
}
m.ReturnType = methodDeclaration.ReturnType.ToTypeReference();
m.ReturnType = ConvertTypeReference(methodDeclaration.ReturnType);
ConvertAttributes(m.Attributes, methodDeclaration.Attributes.Where(s => s.AttributeTarget != "return"));
ConvertAttributes(m.ReturnTypeAttributes, methodDeclaration.Attributes.Where(s => s.AttributeTarget == "return"));
@ -459,16 +452,16 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -459,16 +452,16 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
if (!methodDeclaration.PrivateImplementationType.IsNull) {
m.Accessibility = Accessibility.None;
m.IsExplicitInterfaceImplementation = true;
m.ExplicitInterfaceImplementations.Add(new DefaultMemberReference(
m.EntityType, methodDeclaration.PrivateImplementationType.ToTypeReference(), m.Name,
m.TypeParameters.Count, GetParameterTypes(m.Parameters)));
m.ExplicitInterfaceImplementations.Add(
interningProvider.Intern(new DefaultMemberReference(
m.EntityType,
ConvertTypeReference(methodDeclaration.PrivateImplementationType),
m.Name, m.TypeParameters.Count, GetParameterTypes(m.Parameters))));
}
currentTypeDefinition.Members.Add(m);
currentMethod = null;
if (interningProvider != null) {
m.ApplyInterningProvider(interningProvider);
}
m.ApplyInterningProvider(interningProvider);
return m;
}
@ -480,7 +473,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -480,7 +473,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
for (int i = 0; i < types.Length; i++) {
types[i] = parameters[i].Type;
}
return types;
return interningProvider.InternList(types);
}
bool InheritsConstraints(MethodDeclaration methodDeclaration)
@ -523,30 +516,15 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -523,30 +516,15 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
}
}
var lookupMode = (ownerType == EntityType.TypeDefinition) ? NameLookupMode.BaseTypeReference : NameLookupMode.Type;
tp.Constraints.Add(type.ToTypeReference(lookupMode));
tp.Constraints.Add(ConvertTypeReference(type, lookupMode));
}
break;
}
}
}
}
IMemberReference ConvertInterfaceImplementation(AstType interfaceType, AbstractUnresolvedMember unresolvedMember)
{
ITypeReference interfaceTypeReference = interfaceType.ToTypeReference();
int typeParameterCount = 0;
IList<ITypeReference> parameterTypes = null;
if (unresolvedMember.EntityType == EntityType.Method) {
typeParameterCount = ((IUnresolvedMethod)unresolvedMember).TypeParameters.Count;
foreach (DefaultUnresolvedTypeParameter tp in list) {
tp.ApplyInterningProvider(interningProvider);
}
IUnresolvedParameterizedMember parameterizedMember = unresolvedMember as IUnresolvedParameterizedMember;
if (parameterizedMember != null) {
parameterTypes = new ITypeReference[parameterizedMember.Parameters.Count];
for (int i = 0; i < parameterTypes.Count; i++) {
parameterTypes[i] = parameterizedMember.Parameters[i].Type;
}
}
return new DefaultMemberReference(unresolvedMember.EntityType, interfaceTypeReference, unresolvedMember.Name, typeParameterCount, parameterTypes);
}
#endregion
@ -559,7 +537,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -559,7 +537,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
m.BodyRegion = MakeRegion(operatorDeclaration.Body);
AddXmlDocumentation(m, operatorDeclaration);
m.ReturnType = operatorDeclaration.ReturnType.ToTypeReference();
m.ReturnType = ConvertTypeReference(operatorDeclaration.ReturnType);
ConvertAttributes(m.Attributes, operatorDeclaration.Attributes.Where(s => s.AttributeTarget != "return"));
ConvertAttributes(m.ReturnTypeAttributes, operatorDeclaration.Attributes.Where(s => s.AttributeTarget == "return"));
@ -569,9 +547,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -569,9 +547,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
ConvertParameters(m.Parameters, operatorDeclaration.Parameters);
currentTypeDefinition.Members.Add(m);
if (interningProvider != null) {
m.ApplyInterningProvider(interningProvider);
}
m.ApplyInterningProvider(interningProvider);
return m;
}
#endregion
@ -602,9 +578,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -602,9 +578,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
ApplyModifiers(ctor, modifiers);
currentTypeDefinition.Members.Add(ctor);
if (interningProvider != null) {
ctor.ApplyInterningProvider(interningProvider);
}
ctor.ApplyInterningProvider(interningProvider);
return ctor;
}
#endregion
@ -625,9 +599,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -625,9 +599,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
AddXmlDocumentation(dtor, destructorDeclaration);
currentTypeDefinition.Members.Add(dtor);
if (interningProvider != null) {
dtor.ApplyInterningProvider(interningProvider);
}
dtor.ApplyInterningProvider(interningProvider);
return dtor;
}
#endregion
@ -639,22 +611,20 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -639,22 +611,20 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
p.Region = MakeRegion(propertyDeclaration);
p.BodyRegion = MakeBraceRegion(propertyDeclaration);
ApplyModifiers(p, propertyDeclaration.Modifiers);
p.ReturnType = propertyDeclaration.ReturnType.ToTypeReference();
p.ReturnType = ConvertTypeReference(propertyDeclaration.ReturnType);
ConvertAttributes(p.Attributes, propertyDeclaration.Attributes);
AddXmlDocumentation(p, propertyDeclaration);
if (!propertyDeclaration.PrivateImplementationType.IsNull) {
p.Accessibility = Accessibility.None;
p.IsExplicitInterfaceImplementation = true;
p.ExplicitInterfaceImplementations.Add(new DefaultMemberReference(
p.EntityType, propertyDeclaration.PrivateImplementationType.ToTypeReference(), p.Name));
p.ExplicitInterfaceImplementations.Add(interningProvider.Intern(new DefaultMemberReference(
p.EntityType, ConvertTypeReference(propertyDeclaration.PrivateImplementationType), p.Name)));
}
bool isExtern = propertyDeclaration.HasModifier(Modifiers.Extern);
p.Getter = ConvertAccessor(propertyDeclaration.Getter, p, "get_", isExtern);
p.Setter = ConvertAccessor(propertyDeclaration.Setter, p, "set_", isExtern);
currentTypeDefinition.Members.Add(p);
if (interningProvider != null) {
p.ApplyInterningProvider(interningProvider);
}
p.ApplyInterningProvider(interningProvider);
return p;
}
@ -665,7 +635,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -665,7 +635,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
p.Region = MakeRegion(indexerDeclaration);
p.BodyRegion = MakeBraceRegion(indexerDeclaration);
ApplyModifiers(p, indexerDeclaration.Modifiers);
p.ReturnType = indexerDeclaration.ReturnType.ToTypeReference();
p.ReturnType = ConvertTypeReference(indexerDeclaration.ReturnType);
ConvertAttributes(p.Attributes, indexerDeclaration.Attributes);
AddXmlDocumentation(p, indexerDeclaration);
@ -674,17 +644,15 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -674,17 +644,15 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
if (!indexerDeclaration.PrivateImplementationType.IsNull) {
p.Accessibility = Accessibility.None;
p.IsExplicitInterfaceImplementation = true;
p.ExplicitInterfaceImplementations.Add(new DefaultMemberReference(
p.EntityType, indexerDeclaration.PrivateImplementationType.ToTypeReference(), p.Name, 0, GetParameterTypes(p.Parameters)));
p.ExplicitInterfaceImplementations.Add(interningProvider.Intern(new DefaultMemberReference(
p.EntityType, indexerDeclaration.PrivateImplementationType.ToTypeReference(), p.Name, 0, GetParameterTypes(p.Parameters))));
}
bool isExtern = indexerDeclaration.HasModifier(Modifiers.Extern);
p.Getter = ConvertAccessor(indexerDeclaration.Getter, p, "get_", isExtern);
p.Setter = ConvertAccessor(indexerDeclaration.Setter, p, "set_", isExtern);
currentTypeDefinition.Members.Add(p);
if (interningProvider != null) {
p.ApplyInterningProvider(interningProvider);
}
p.ApplyInterningProvider(interningProvider);
return p;
}
@ -705,7 +673,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -705,7 +673,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
a.Region = MakeRegion(accessor);
a.BodyRegion = MakeRegion(accessor.Body);
// An accessor has no body if all both are true:
// An accessor has no body if both are true:
// a) there's no body in the code
// b) the member is either abstract or extern
a.HasBody = !(accessor.Body.IsNull && (p.IsAbstract || memberIsExtern));
@ -733,12 +701,13 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -733,12 +701,13 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
if (p.IsExplicitInterfaceImplementation) {
a.IsExplicitInterfaceImplementation = true;
Debug.Assert(p.ExplicitInterfaceImplementations.Count == 1);
a.ExplicitInterfaceImplementations.Add(new DefaultMemberReference(
a.ExplicitInterfaceImplementations.Add(interningProvider.Intern(new DefaultMemberReference(
EntityType.Accessor,
p.ExplicitInterfaceImplementations[0].DeclaringTypeReference,
a.Name, 0, GetParameterTypes(a.Parameters)
));
)));
}
a.ApplyInterningProvider(interningProvider);
return a;
}
#endregion
@ -758,7 +727,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -758,7 +727,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
ApplyModifiers(ev, modifiers);
AddXmlDocumentation(ev, eventDeclaration);
ev.ReturnType = eventDeclaration.ReturnType.ToTypeReference();
ev.ReturnType = ConvertTypeReference(eventDeclaration.ReturnType);
var valueParameter = new DefaultUnresolvedParameter(ev.ReturnType, "value");
ev.AddAccessor = CreateDefaultEventAccessor(ev, "add_" + ev.Name, valueParameter);
@ -777,9 +746,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -777,9 +746,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
}
currentTypeDefinition.Members.Add(ev);
if (interningProvider != null) {
ev.ApplyInterningProvider(interningProvider);
}
ev.ApplyInterningProvider(interningProvider);
}
return isSingleEvent ? ev : null;
}
@ -810,15 +777,15 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -810,15 +777,15 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
e.Region = MakeRegion(eventDeclaration);
e.BodyRegion = MakeBraceRegion(eventDeclaration);
ApplyModifiers(e, eventDeclaration.Modifiers);
e.ReturnType = eventDeclaration.ReturnType.ToTypeReference();
e.ReturnType = ConvertTypeReference(eventDeclaration.ReturnType);
ConvertAttributes(e.Attributes, eventDeclaration.Attributes);
AddXmlDocumentation(e, eventDeclaration);
if (!eventDeclaration.PrivateImplementationType.IsNull) {
e.Accessibility = Accessibility.None;
e.IsExplicitInterfaceImplementation = true;
e.ExplicitInterfaceImplementations.Add(new DefaultMemberReference(
e.EntityType, eventDeclaration.PrivateImplementationType.ToTypeReference(), e.Name));
e.ExplicitInterfaceImplementations.Add(interningProvider.Intern(new DefaultMemberReference(
e.EntityType, eventDeclaration.PrivateImplementationType.ToTypeReference(), e.Name)));
}
// custom events can't be extern; the non-custom event syntax must be used for extern events
@ -826,9 +793,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -826,9 +793,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
e.RemoveAccessor = ConvertAccessor(eventDeclaration.RemoveAccessor, e, "remove_", false);
currentTypeDefinition.Members.Add(e);
if (interningProvider != null) {
e.ApplyInterningProvider(interningProvider);
}
e.ApplyInterningProvider(interningProvider);
return e;
}
#endregion
@ -904,18 +869,18 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -904,18 +869,18 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
}
}
internal static ITypeReference ConvertAttributeType(AstType type)
internal static ITypeReference ConvertAttributeType(AstType type, InterningProvider interningProvider)
{
ITypeReference tr = type.ToTypeReference();
ITypeReference tr = type.ToTypeReference(NameLookupMode.Type, interningProvider);
if (!type.GetChildByRole(Roles.Identifier).IsVerbatim) {
// Try to add "Attribute" suffix, but only if the identifier
// (=last identifier in fully qualified name) isn't a verbatim identifier.
SimpleTypeOrNamespaceReference st = tr as SimpleTypeOrNamespaceReference;
MemberTypeOrNamespaceReference mt = tr as MemberTypeOrNamespaceReference;
if (st != null)
return new AttributeTypeReference(st, st.AddSuffix("Attribute"));
return interningProvider.Intern(new AttributeTypeReference(st, interningProvider.Intern(st.AddSuffix("Attribute"))));
else if (mt != null)
return new AttributeTypeReference(mt, mt.AddSuffix("Attribute"));
return interningProvider.Intern(new AttributeTypeReference(mt, interningProvider.Intern(mt.AddSuffix("Attribute"))));
}
return tr;
}
@ -923,20 +888,21 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -923,20 +888,21 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
CSharpAttribute ConvertAttribute(CSharp.Attribute attr)
{
DomRegion region = MakeRegion(attr);
ITypeReference type = ConvertAttributeType(attr.Type);
ITypeReference type = ConvertAttributeType(attr.Type, interningProvider);
List<IConstantValue> positionalArguments = null;
List<KeyValuePair<string, IConstantValue>> namedCtorArguments = null;
List<KeyValuePair<string, IConstantValue>> namedArguments = null;
foreach (Expression expr in attr.Arguments) {
NamedArgumentExpression nae = expr as NamedArgumentExpression;
if (nae != null) {
string name = interningProvider.Intern(nae.Name);
if (namedCtorArguments == null)
namedCtorArguments = new List<KeyValuePair<string, IConstantValue>>();
namedCtorArguments.Add(new KeyValuePair<string, IConstantValue>(nae.Name, ConvertAttributeArgument(nae.Expression)));
namedCtorArguments.Add(new KeyValuePair<string, IConstantValue>(name, ConvertAttributeArgument(nae.Expression)));
} else {
NamedExpression namedExpression = expr as NamedExpression;
if (namedExpression != null) {
string name = namedExpression.Name;
string name = interningProvider.Intern(namedExpression.Name);
if (namedArguments == null)
namedArguments = new List<KeyValuePair<string, IConstantValue>>();
namedArguments.Add(new KeyValuePair<string, IConstantValue>(name, ConvertAttributeArgument(namedExpression.Expression)));
@ -947,53 +913,55 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -947,53 +913,55 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
}
}
}
return new CSharpAttribute(type, region, positionalArguments, namedCtorArguments, namedArguments);
return new CSharpAttribute(type, region, interningProvider.InternList(positionalArguments), namedCtorArguments, namedArguments);
}
#endregion
#region Types
[Obsolete("Use AstType.ToTypeReference() instead.")]
public static ITypeReference ConvertType(AstType type, NameLookupMode lookupMode = NameLookupMode.Type)
ITypeReference ConvertTypeReference(AstType type, NameLookupMode lookupMode = NameLookupMode.Type)
{
return type.ToTypeReference(lookupMode);
return type.ToTypeReference(lookupMode, interningProvider);
}
#endregion
#region Constant Values
IConstantValue ConvertConstantValue(ITypeReference targetType, AstNode expression)
{
return ConvertConstantValue(targetType, expression, currentTypeDefinition, currentMethod, usingScope);
return ConvertConstantValue(targetType, expression, currentTypeDefinition, currentMethod, usingScope, interningProvider);
}
internal static IConstantValue ConvertConstantValue(
ITypeReference targetType, AstNode expression,
IUnresolvedTypeDefinition parentTypeDefinition, IUnresolvedMethod parentMethodDefinition, UsingScope parentUsingScope)
IUnresolvedTypeDefinition parentTypeDefinition, IUnresolvedMethod parentMethodDefinition, UsingScope parentUsingScope,
InterningProvider interningProvider)
{
ConstantValueBuilder b = new ConstantValueBuilder(false);
ConstantValueBuilder b = new ConstantValueBuilder(false, interningProvider);
ConstantExpression c = expression.AcceptVisitor(b);
if (c == null)
return new ErrorConstantValue(targetType);
PrimitiveConstantExpression pc = c as PrimitiveConstantExpression;
if (pc != null && pc.Type == targetType) {
// Save memory by directly using a SimpleConstantValue.
return new SimpleConstantValue(targetType, pc.Value);
return interningProvider.Intern(new SimpleConstantValue(targetType, pc.Value));
}
// cast to the desired type
return new ConstantCast(targetType, c);
return interningProvider.Intern(new ConstantCast(targetType, c));
}
IConstantValue ConvertAttributeArgument(Expression expression)
{
ConstantValueBuilder b = new ConstantValueBuilder(true);
ConstantValueBuilder b = new ConstantValueBuilder(true, interningProvider);
return expression.AcceptVisitor(b);
}
sealed class ConstantValueBuilder : DepthFirstAstVisitor<ConstantExpression>
{
readonly InterningProvider interningProvider;
readonly bool isAttributeArgument;
public ConstantValueBuilder(bool isAttributeArgument)
public ConstantValueBuilder(bool isAttributeArgument, InterningProvider interningProvider)
{
this.interningProvider = interningProvider;
this.isAttributeArgument = isAttributeArgument;
}
@ -1004,13 +972,21 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -1004,13 +972,21 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
public override ConstantExpression VisitNullReferenceExpression(NullReferenceExpression nullReferenceExpression)
{
return new PrimitiveConstantExpression(KnownTypeReference.Object, null);
return interningProvider.Intern(
new PrimitiveConstantExpression(KnownTypeReference.Object, null));
}
public override ConstantExpression VisitPrimitiveExpression(PrimitiveExpression primitiveExpression)
{
TypeCode typeCode = Type.GetTypeCode(primitiveExpression.Value.GetType());
return new PrimitiveConstantExpression(typeCode.ToTypeReference(), primitiveExpression.Value);
object val = interningProvider.InternValue(primitiveExpression.Value);
TypeCode typeCode = Type.GetTypeCode(val.GetType());
return interningProvider.Intern(
new PrimitiveConstantExpression(typeCode.ToTypeReference(), val));
}
ITypeReference ConvertTypeReference(AstType type)
{
return type.ToTypeReference(NameLookupMode.Type, interningProvider);
}
IList<ITypeReference> ConvertTypeArguments(AstNodeCollection<AstType> types)
@ -1021,31 +997,33 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -1021,31 +997,33 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
ITypeReference[] result = new ITypeReference[count];
int pos = 0;
foreach (AstType type in types) {
result[pos++] = type.ToTypeReference();
result[pos++] = ConvertTypeReference(type);
}
return result;
return interningProvider.InternList(result);
}
public override ConstantExpression VisitIdentifierExpression(IdentifierExpression identifierExpression)
{
return new ConstantIdentifierReference(identifierExpression.Identifier, ConvertTypeArguments(identifierExpression.TypeArguments));
string identifier = interningProvider.Intern(identifierExpression.Identifier);
return new ConstantIdentifierReference(identifier, ConvertTypeArguments(identifierExpression.TypeArguments));
}
public override ConstantExpression VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression)
{
string memberName = interningProvider.Intern(memberReferenceExpression.MemberName);
TypeReferenceExpression tre = memberReferenceExpression.Target as TypeReferenceExpression;
if (tre != null) {
// handle "int.MaxValue"
return new ConstantMemberReference(
tre.Type.ToTypeReference(),
memberReferenceExpression.MemberName,
ConvertTypeReference(tre.Type),
memberName,
ConvertTypeArguments(memberReferenceExpression.TypeArguments));
}
ConstantExpression v = memberReferenceExpression.Target.AcceptVisitor(this);
if (v == null)
return null;
return new ConstantMemberReference(
v, memberReferenceExpression.MemberName,
v, memberName,
ConvertTypeArguments(memberReferenceExpression.TypeArguments));
}
@ -1059,7 +1037,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -1059,7 +1037,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
ConstantExpression v = castExpression.Expression.AcceptVisitor(this);
if (v == null)
return null;
return new ConstantCast(castExpression.Type.ToTypeReference(), v);
return interningProvider.Intern(new ConstantCast(ConvertTypeReference(castExpression.Type), v));
}
public override ConstantExpression VisitCheckedExpression(CheckedExpression checkedExpression)
@ -1082,7 +1060,8 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -1082,7 +1060,8 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
public override ConstantExpression VisitDefaultValueExpression(DefaultValueExpression defaultValueExpression)
{
return new ConstantDefaultValue(defaultValueExpression.Type.ToTypeReference());
return interningProvider.Intern(
new ConstantDefaultValue(ConvertTypeReference(defaultValueExpression.Type)));
}
public override ConstantExpression VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression)
@ -1113,7 +1092,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -1113,7 +1092,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
public override ConstantExpression VisitTypeOfExpression(TypeOfExpression typeOfExpression)
{
if (isAttributeArgument) {
return new TypeOfConstantExpression(typeOfExpression.Type.ToTypeReference());
return new TypeOfConstantExpression(ConvertTypeReference(typeOfExpression.Type));
} else {
return null;
}
@ -1128,9 +1107,9 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -1128,9 +1107,9 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
if (arrayCreateExpression.Type.IsNull) {
type = null;
} else {
type = arrayCreateExpression.Type.ToTypeReference();
type = ConvertTypeReference(arrayCreateExpression.Type);
foreach (var spec in arrayCreateExpression.AdditionalArraySpecifiers.Reverse()) {
type = new ArrayTypeReference(type, spec.Dimensions);
type = interningProvider.Intern(new ArrayTypeReference(type, spec.Dimensions));
}
}
ConstantExpression[] elements = new ConstantExpression[initializer.Elements.Count];
@ -1153,17 +1132,17 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -1153,17 +1132,17 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
void ConvertParameters(IList<IUnresolvedParameter> outputList, IEnumerable<ParameterDeclaration> parameters)
{
foreach (ParameterDeclaration pd in parameters) {
DefaultUnresolvedParameter p = new DefaultUnresolvedParameter(pd.Type.ToTypeReference(), pd.Name);
DefaultUnresolvedParameter p = new DefaultUnresolvedParameter(ConvertTypeReference(pd.Type), interningProvider.Intern(pd.Name));
p.Region = MakeRegion(pd);
ConvertAttributes(p.Attributes, pd.Attributes);
switch (pd.ParameterModifier) {
case ParameterModifier.Ref:
p.IsRef = true;
p.Type = new ByReferenceTypeReference(p.Type);
p.Type = interningProvider.Intern(new ByReferenceTypeReference(p.Type));
break;
case ParameterModifier.Out:
p.IsOut = true;
p.Type = new ByReferenceTypeReference(p.Type);
p.Type = interningProvider.Intern(new ByReferenceTypeReference(p.Type));
break;
case ParameterModifier.Params:
p.IsParams = true;
@ -1171,17 +1150,17 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -1171,17 +1150,17 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
}
if (!pd.DefaultExpression.IsNull)
p.DefaultValue = ConvertConstantValue(p.Type, pd.DefaultExpression);
outputList.Add(p);
outputList.Add(interningProvider.Intern(p));
}
}
internal static IList<ITypeReference> GetParameterTypes(IEnumerable<ParameterDeclaration> parameters)
internal static IList<ITypeReference> GetParameterTypes(IEnumerable<ParameterDeclaration> parameters, InterningProvider interningProvider)
{
List<ITypeReference> result = new List<ITypeReference>();
foreach (ParameterDeclaration pd in parameters) {
ITypeReference type = pd.Type.ToTypeReference();
ITypeReference type = pd.Type.ToTypeReference(NameLookupMode.Type, interningProvider);
if (pd.ParameterModifier == ParameterModifier.Ref || pd.ParameterModifier == ParameterModifier.Out)
type = new ByReferenceTypeReference(type);
type = interningProvider.Intern(new ByReferenceTypeReference(type));
result.Add(type);
}
return result;

4
ICSharpCode.NRefactory/Documentation/IdStringProvider.cs

@ -285,11 +285,11 @@ namespace ICSharpCode.NRefactory.Documentation @@ -285,11 +285,11 @@ namespace ICSharpCode.NRefactory.Documentation
// method type parameter reference
pos++;
int index = ReflectionHelper.ReadTypeParameterCount(reflectionTypeName, ref pos);
result = new TypeParameterReference(EntityType.Method, index);
result = TypeParameterReference.Create(EntityType.Method, index);
} else {
// class type parameter reference
int index = ReflectionHelper.ReadTypeParameterCount(reflectionTypeName, ref pos);
result = new TypeParameterReference(EntityType.TypeDefinition, index);
result = TypeParameterReference.Create(EntityType.TypeDefinition, index);
}
} else {
// not a type parameter reference: read the actual type name

9
ICSharpCode.NRefactory/TypeSystem/ArrayType.cs

@ -147,8 +147,8 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -147,8 +147,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
[Serializable]
public sealed class ArrayTypeReference : ITypeReference, ISupportsInterning
{
ITypeReference elementType;
int dimensions;
readonly ITypeReference elementType;
readonly int dimensions;
public ArrayTypeReference(ITypeReference elementType, int dimensions = 1)
{
@ -178,11 +178,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -178,11 +178,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
return elementType.ToString() + "[" + new string(',', dimensions - 1) + "]";
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
elementType = provider.Intern(elementType);
}
int ISupportsInterning.GetHashCodeForInterning()
{
return elementType.GetHashCode() ^ dimensions;

7
ICSharpCode.NRefactory/TypeSystem/ByReferenceType.cs

@ -75,7 +75,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -75,7 +75,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
[Serializable]
public sealed class ByReferenceTypeReference : ITypeReference, ISupportsInterning
{
ITypeReference elementType;
readonly ITypeReference elementType;
public ByReferenceTypeReference(ITypeReference elementType)
{
@ -98,11 +98,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -98,11 +98,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
return elementType.ToString() + "&";
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
elementType = provider.Intern(elementType);
}
int ISupportsInterning.GetHashCodeForInterning()
{
return elementType.GetHashCode() ^ 91725814;

207
ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs

@ -72,10 +72,19 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -72,10 +72,19 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// </summary>
public IDocumentationProvider DocumentationProvider { get; set; }
InterningProvider interningProvider;
/// <summary>
/// Gets/Sets the interning provider.
/// </summary>
public IInterningProvider InterningProvider { get; set; }
public InterningProvider InterningProvider {
get { return interningProvider; }
set {
if (value == null)
throw new ArgumentNullException();
interningProvider = value;
}
}
/// <summary>
/// Gets/Sets the cancellation token used by the cecil loader.
@ -140,6 +149,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -140,6 +149,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
this.currentModule = loader.currentModule;
this.currentAssembly = loader.currentAssembly;
// don't use interning - the interning provider is most likely not thread-safe
this.interningProvider = InterningProvider.Dummy;
// don't use cancellation for delay-loaded members
}
@ -162,10 +172,8 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -162,10 +172,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
AddAttributes(assemblyDefinition, assemblyAttributes);
AddAttributes(assemblyDefinition.MainModule, moduleAttributes);
if (this.InterningProvider != null) {
assemblyAttributes = this.InterningProvider.InternList(assemblyAttributes);
moduleAttributes = this.InterningProvider.InternList(moduleAttributes);
}
assemblyAttributes = interningProvider.InternList(assemblyAttributes);
moduleAttributes = interningProvider.InternList(moduleAttributes);
this.currentAssembly = new CecilUnresolvedAssembly(assemblyDefinition.Name.Name, this.DocumentationProvider);
currentAssembly.Location = assemblyDefinition.MainModule.FullyQualifiedName;
@ -176,11 +184,13 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -176,11 +184,13 @@ namespace ICSharpCode.NRefactory.TypeSystem
foreach (ExportedType type in assemblyDefinition.MainModule.ExportedTypes) {
if (type.IsForwarder) {
int typeParameterCount;
string ns = type.Namespace;
string name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(type.Name, out typeParameterCount);
var typeRef = new GetClassTypeReference(GetAssemblyReference(type.Scope), type.Namespace, name, typeParameterCount);
if (this.InterningProvider != null)
typeRef = this.InterningProvider.Intern(typeRef);
var key = new FullNameAndTypeParameterCount(type.Namespace, name, typeParameterCount);
ns = interningProvider.Intern(ns);
name = interningProvider.Intern(name);
var typeRef = new GetClassTypeReference(GetAssemblyReference(type.Scope), ns, name, typeParameterCount);
typeRef = interningProvider.Intern(typeRef);
var key = new FullNameAndTypeParameterCount(ns, name, typeParameterCount);
currentAssembly.AddTypeForwarder(key, typeRef);
}
}
@ -335,23 +345,26 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -335,23 +345,26 @@ namespace ICSharpCode.NRefactory.TypeSystem
if (type is Mono.Cecil.ByReferenceType) {
typeIndex++;
return new ByReferenceTypeReference(
CreateType(
(type as Mono.Cecil.ByReferenceType).ElementType,
typeAttributes, ref typeIndex));
return interningProvider.Intern(
new ByReferenceTypeReference(
CreateType(
(type as Mono.Cecil.ByReferenceType).ElementType,
typeAttributes, ref typeIndex)));
} else if (type is Mono.Cecil.PointerType) {
typeIndex++;
return new PointerTypeReference(
CreateType(
(type as Mono.Cecil.PointerType).ElementType,
typeAttributes, ref typeIndex));
return interningProvider.Intern(
new PointerTypeReference(
CreateType(
(type as Mono.Cecil.PointerType).ElementType,
typeAttributes, ref typeIndex)));
} else if (type is Mono.Cecil.ArrayType) {
typeIndex++;
return new ArrayTypeReference(
CreateType(
(type as Mono.Cecil.ArrayType).ElementType,
typeAttributes, ref typeIndex),
(type as Mono.Cecil.ArrayType).Rank);
return interningProvider.Intern(
new ArrayTypeReference(
CreateType(
(type as Mono.Cecil.ArrayType).ElementType,
typeAttributes, ref typeIndex),
(type as Mono.Cecil.ArrayType).Rank));
} else if (type is GenericInstanceType) {
GenericInstanceType gType = (GenericInstanceType)type;
ITypeReference baseType = CreateType(gType.ElementType, typeAttributes, ref typeIndex);
@ -360,17 +373,18 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -360,17 +373,18 @@ namespace ICSharpCode.NRefactory.TypeSystem
typeIndex++;
para[i] = CreateType(gType.GenericArguments[i], typeAttributes, ref typeIndex);
}
return new ParameterizedTypeReference(baseType, para);
return interningProvider.Intern(new ParameterizedTypeReference(baseType, para));
} else if (type is GenericParameter) {
GenericParameter typeGP = (GenericParameter)type;
return new TypeParameterReference(typeGP.Owner is MethodDefinition ? EntityType.Method : EntityType.TypeDefinition, typeGP.Position);
return TypeParameterReference.Create(typeGP.Owner is MethodDefinition ? EntityType.Method : EntityType.TypeDefinition, typeGP.Position);
} else if (type.IsNested) {
ITypeReference typeRef = CreateType(type.DeclaringType, typeAttributes, ref typeIndex);
int partTypeParameterCount;
string namepart = ReflectionHelper.SplitTypeParameterCountFromReflectionName(type.Name, out partTypeParameterCount);
return new NestedTypeReference(typeRef, namepart, partTypeParameterCount);
namepart = interningProvider.Intern(namepart);
return interningProvider.Intern(new NestedTypeReference(typeRef, namepart, partTypeParameterCount));
} else {
string ns = type.Namespace ?? string.Empty;
string ns = interningProvider.Intern(type.Namespace ?? string.Empty);
string name = type.Name;
if (name == null)
throw new InvalidOperationException("type.Name returned null. Type: " + type.ToString());
@ -380,12 +394,13 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -380,12 +394,13 @@ namespace ICSharpCode.NRefactory.TypeSystem
} else {
int typeParameterCount;
name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(name, out typeParameterCount);
name = interningProvider.Intern(name);
if (currentAssembly != null) {
IUnresolvedTypeDefinition c = currentAssembly.GetTypeDefinition(ns, name, typeParameterCount);
if (c != null)
return c;
}
return new GetClassTypeReference(GetAssemblyReference(type.Scope), ns, name, typeParameterCount);
return interningProvider.Intern(new GetClassTypeReference(GetAssemblyReference(type.Scope), ns, name, typeParameterCount));
}
}
}
@ -395,7 +410,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -395,7 +410,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
if (scope == null || scope == currentModule)
return DefaultAssemblyReference.CurrentAssembly;
else
return new DefaultAssemblyReference(scope.Name);
return interningProvider.Intern(new DefaultAssemblyReference(scope.Name));
}
static bool HasDynamicAttribute(ICustomAttributeProvider attributeProvider, int typeIndex)
@ -433,10 +448,15 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -433,10 +448,15 @@ namespace ICSharpCode.NRefactory.TypeSystem
// AssemblyVersionAttribute
if (assembly.Name.Version != null) {
var assemblyVersion = new DefaultUnresolvedAttribute(assemblyVersionAttributeTypeRef, new[] { KnownTypeReference.String });
assemblyVersion.PositionalArguments.Add(new SimpleConstantValue(KnownTypeReference.String, assembly.Name.Version.ToString()));
outputList.Add(assemblyVersion);
assemblyVersion.PositionalArguments.Add(CreateSimpleConstantValue(KnownTypeReference.String, assembly.Name.Version.ToString()));
outputList.Add(interningProvider.Intern(assemblyVersion));
}
}
IConstantValue CreateSimpleConstantValue(ITypeReference type, object value)
{
return interningProvider.Intern(new SimpleConstantValue(type, interningProvider.InternValue(value)));
}
#endregion
#region Module Attributes
@ -497,7 +517,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -497,7 +517,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
if (methodDefinition.HasPInvokeInfo) {
PInvokeInfo info = methodDefinition.PInvokeInfo;
var dllImport = new DefaultUnresolvedAttribute(dllImportAttributeTypeRef, new[] { KnownTypeReference.String });
dllImport.PositionalArguments.Add(new SimpleConstantValue(KnownTypeReference.String, info.Module.Name));
dllImport.PositionalArguments.Add(CreateSimpleConstantValue(KnownTypeReference.String, info.Module.Name));
if (info.IsBestFitDisabled)
dllImport.AddNamedFieldArgument("BestFitMapping", falseValue);
@ -529,7 +549,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -529,7 +549,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
throw new NotSupportedException("unknown calling convention");
}
if (callingConvention != CallingConvention.Winapi)
dllImport.AddNamedFieldArgument("CallingConvention", callingConventionTypeRef, (int)callingConvention);
dllImport.AddNamedFieldArgument("CallingConvention", CreateSimpleConstantValue(callingConventionTypeRef, (int)callingConvention));
CharSet charSet = CharSet.None;
switch (info.Attributes & PInvokeAttributes.CharSetMask) {
@ -544,10 +564,10 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -544,10 +564,10 @@ namespace ICSharpCode.NRefactory.TypeSystem
break;
}
if (charSet != CharSet.None)
dllImport.AddNamedFieldArgument("CharSet", charSetTypeRef, (int)charSet);
dllImport.AddNamedFieldArgument("CharSet", CreateSimpleConstantValue(charSetTypeRef, (int)charSet));
if (!string.IsNullOrEmpty(info.EntryPoint) && info.EntryPoint != methodDefinition.Name)
dllImport.AddNamedFieldArgument("EntryPoint", KnownTypeReference.String, info.EntryPoint);
dllImport.AddNamedFieldArgument("EntryPoint", CreateSimpleConstantValue(KnownTypeReference.String, info.EntryPoint));
if (info.IsNoMangle)
dllImport.AddNamedFieldArgument("ExactSpelling", trueValue);
@ -565,7 +585,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -565,7 +585,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
if (info.IsThrowOnUnmappableCharEnabled)
dllImport.AddNamedFieldArgument("ThrowOnUnmappableChar", trueValue);
attributes.Add(dllImport);
attributes.Add(interningProvider.Intern(dllImport));
}
#endregion
@ -579,8 +599,8 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -579,8 +599,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
#region MethodImplAttribute
if (implAttributes != 0) {
var methodImpl = new DefaultUnresolvedAttribute(methodImplAttributeTypeRef, new[] { methodImplOptionsTypeRef });
methodImpl.PositionalArguments.Add(new SimpleConstantValue(methodImplOptionsTypeRef, (int)implAttributes));
attributes.Add(methodImpl);
methodImpl.PositionalArguments.Add(CreateSimpleConstantValue(methodImplOptionsTypeRef, (int)implAttributes));
attributes.Add(interningProvider.Intern(methodImpl));
}
#endregion
@ -641,17 +661,17 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -641,17 +661,17 @@ namespace ICSharpCode.NRefactory.TypeSystem
LayoutKind defaultLayoutKind = (typeDefinition.IsValueType && !typeDefinition.IsEnum) ? LayoutKind.Sequential: LayoutKind.Auto;
if (layoutKind != defaultLayoutKind || charSet != CharSet.Ansi || typeDefinition.PackingSize > 0 || typeDefinition.ClassSize > 0) {
DefaultUnresolvedAttribute structLayout = new DefaultUnresolvedAttribute(structLayoutAttributeTypeRef, new[] { layoutKindTypeRef });
structLayout.PositionalArguments.Add(new SimpleConstantValue(layoutKindTypeRef, (int)layoutKind));
structLayout.PositionalArguments.Add(CreateSimpleConstantValue(layoutKindTypeRef, (int)layoutKind));
if (charSet != CharSet.Ansi) {
structLayout.AddNamedFieldArgument("CharSet", charSetTypeRef, (int)charSet);
structLayout.AddNamedFieldArgument("CharSet", CreateSimpleConstantValue(charSetTypeRef, (int)charSet));
}
if (typeDefinition.PackingSize > 0) {
structLayout.AddNamedFieldArgument("Pack", KnownTypeReference.Int32, (int)typeDefinition.PackingSize);
structLayout.AddNamedFieldArgument("Pack", CreateSimpleConstantValue(KnownTypeReference.Int32, (int)typeDefinition.PackingSize));
}
if (typeDefinition.ClassSize > 0) {
structLayout.AddNamedFieldArgument("Size", KnownTypeReference.Int32, (int)typeDefinition.ClassSize);
structLayout.AddNamedFieldArgument("Size", CreateSimpleConstantValue(KnownTypeReference.Int32, (int)typeDefinition.ClassSize));
}
targetEntity.Attributes.Add(structLayout);
targetEntity.Attributes.Add(interningProvider.Intern(structLayout));
}
#endregion
@ -673,8 +693,8 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -673,8 +693,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
// FieldOffsetAttribute
if (fieldDefinition.HasLayoutInfo) {
DefaultUnresolvedAttribute fieldOffset = new DefaultUnresolvedAttribute(fieldOffsetAttributeTypeRef, new[] { KnownTypeReference.Int32 });
fieldOffset.PositionalArguments.Add(new SimpleConstantValue(KnownTypeReference.Int32, fieldDefinition.Offset));
targetEntity.Attributes.Add(fieldOffset);
fieldOffset.PositionalArguments.Add(CreateSimpleConstantValue(KnownTypeReference.Int32, fieldDefinition.Offset));
targetEntity.Attributes.Add(interningProvider.Intern(fieldOffset));
}
// NonSerializedAttribute
@ -714,42 +734,42 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -714,42 +734,42 @@ namespace ICSharpCode.NRefactory.TypeSystem
static readonly ITypeReference marshalAsAttributeTypeRef = typeof(MarshalAsAttribute).ToTypeReference();
static readonly ITypeReference unmanagedTypeTypeRef = typeof(UnmanagedType).ToTypeReference();
static IUnresolvedAttribute ConvertMarshalInfo(MarshalInfo marshalInfo)
IUnresolvedAttribute ConvertMarshalInfo(MarshalInfo marshalInfo)
{
DefaultUnresolvedAttribute attr = new DefaultUnresolvedAttribute(marshalAsAttributeTypeRef, new[] { unmanagedTypeTypeRef });
attr.PositionalArguments.Add(new SimpleConstantValue(unmanagedTypeTypeRef, (int)marshalInfo.NativeType));
attr.PositionalArguments.Add(CreateSimpleConstantValue(unmanagedTypeTypeRef, (int)marshalInfo.NativeType));
FixedArrayMarshalInfo fami = marshalInfo as FixedArrayMarshalInfo;
if (fami != null) {
attr.AddNamedFieldArgument("SizeConst", KnownTypeReference.Int32, (int)fami.Size);
attr.AddNamedFieldArgument("SizeConst", CreateSimpleConstantValue(KnownTypeReference.Int32, (int)fami.Size));
if (fami.ElementType != NativeType.None)
attr.AddNamedFieldArgument("ArraySubType", unmanagedTypeTypeRef, (int)fami.ElementType);
attr.AddNamedFieldArgument("ArraySubType", CreateSimpleConstantValue(unmanagedTypeTypeRef, (int)fami.ElementType));
}
SafeArrayMarshalInfo sami = marshalInfo as SafeArrayMarshalInfo;
if (sami != null && sami.ElementType != VariantType.None) {
attr.AddNamedFieldArgument("SafeArraySubType", typeof(VarEnum).ToTypeReference(), (int)sami.ElementType);
attr.AddNamedFieldArgument("SafeArraySubType", CreateSimpleConstantValue(typeof(VarEnum).ToTypeReference(), (int)sami.ElementType));
}
ArrayMarshalInfo ami = marshalInfo as ArrayMarshalInfo;
if (ami != null) {
if (ami.ElementType != NativeType.Max)
attr.AddNamedFieldArgument("ArraySubType", unmanagedTypeTypeRef, (int)ami.ElementType);
attr.AddNamedFieldArgument("ArraySubType", CreateSimpleConstantValue(unmanagedTypeTypeRef, (int)ami.ElementType));
if (ami.Size >= 0)
attr.AddNamedFieldArgument("SizeConst", KnownTypeReference.Int32, (int)ami.Size);
attr.AddNamedFieldArgument("SizeConst", CreateSimpleConstantValue(KnownTypeReference.Int32, (int)ami.Size));
if (ami.SizeParameterMultiplier != 0 && ami.SizeParameterIndex >= 0)
attr.AddNamedFieldArgument("SizeParamIndex", KnownTypeReference.Int16, (short)ami.SizeParameterIndex);
attr.AddNamedFieldArgument("SizeParamIndex", CreateSimpleConstantValue(KnownTypeReference.Int16, (short)ami.SizeParameterIndex));
}
CustomMarshalInfo cmi = marshalInfo as CustomMarshalInfo;
if (cmi != null) {
attr.AddNamedFieldArgument("MarshalType", KnownTypeReference.String, cmi.ManagedType.FullName);
attr.AddNamedFieldArgument("MarshalType", CreateSimpleConstantValue(KnownTypeReference.String, cmi.ManagedType.FullName));
if (!string.IsNullOrEmpty(cmi.Cookie))
attr.AddNamedFieldArgument("MarshalCookie", KnownTypeReference.String, cmi.Cookie);
attr.AddNamedFieldArgument("MarshalCookie", CreateSimpleConstantValue(KnownTypeReference.String, cmi.Cookie));
}
FixedSysStringMarshalInfo fssmi = marshalInfo as FixedSysStringMarshalInfo;
if (fssmi != null) {
attr.AddNamedFieldArgument("SizeConst", KnownTypeReference.Int32, (int)fssmi.Size);
attr.AddNamedFieldArgument("SizeConst", CreateSimpleConstantValue(KnownTypeReference.Int32, (int)fssmi.Size));
}
return attr;
return InterningProvider.Intern(attr);
}
#endregion
@ -775,18 +795,15 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -775,18 +795,15 @@ namespace ICSharpCode.NRefactory.TypeSystem
throw new ArgumentNullException("attribute");
MethodReference ctor = attribute.Constructor;
ITypeReference attributeType = ReadTypeReference(attribute.AttributeType);
IList<ITypeReference> ctorParameterTypes = null;
IList<ITypeReference> ctorParameterTypes = EmptyList<ITypeReference>.Instance;
if (ctor.HasParameters) {
ctorParameterTypes = new ITypeReference[ctor.Parameters.Count];
for (int i = 0; i < ctorParameterTypes.Count; i++) {
ctorParameterTypes[i] = ReadTypeReference(ctor.Parameters[i].ParameterType);
}
ctorParameterTypes = interningProvider.InternList(ctorParameterTypes);
}
if (this.InterningProvider != null) {
attributeType = this.InterningProvider.Intern(attributeType);
ctorParameterTypes = this.InterningProvider.InternList(ctorParameterTypes);
}
return new CecilUnresolvedAttribute(attributeType, ctorParameterTypes ?? EmptyList<ITypeReference>.Instance, attribute.GetBlob());
return interningProvider.Intern(new CecilUnresolvedAttribute(attributeType, ctorParameterTypes, attribute.GetBlob()));
}
#endregion
@ -842,11 +859,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -842,11 +859,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
return new CecilResolvedAttribute(context, this);
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
// We already interned our child elements in ReadAttribute().
}
int ISupportsInterning.GetHashCodeForInterning()
{
return attributeType.GetHashCode() ^ ctorParameterTypes.GetHashCode() ^ GetBlobHashCode(blob);
@ -1357,11 +1369,9 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1357,11 +1369,9 @@ namespace ICSharpCode.NRefactory.TypeSystem
// binary attribute
uint attributeCount = reader.ReadCompressedUInt32();
UnresolvedSecurityDeclaration unresolvedSecDecl = new UnresolvedSecurityDeclaration(securityAction, blob);
if (this.InterningProvider != null) {
unresolvedSecDecl = this.InterningProvider.Intern(unresolvedSecDecl);
}
unresolvedSecDecl = interningProvider.Intern(unresolvedSecDecl);
for (uint i = 0; i < attributeCount; i++) {
targetCollection.Add(new UnresolvedSecurityAttribute(unresolvedSecDecl, (int)i));
targetCollection.Add(interningProvider.Intern(new UnresolvedSecurityAttribute(unresolvedSecDecl, (int)i)));
}
} else {
// for backward compatibility with .NET 1.0: XML-encoded attribute
@ -1369,16 +1379,16 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1369,16 +1379,16 @@ namespace ICSharpCode.NRefactory.TypeSystem
attr.ConstructorParameterTypes.Add(securityActionTypeReference);
attr.PositionalArguments.Add(securityAction);
string xml = System.Text.Encoding.Unicode.GetString(blob);
attr.AddNamedPropertyArgument("XML", KnownTypeReference.String, xml);
targetCollection.Add(attr);
attr.AddNamedPropertyArgument("XML", CreateSimpleConstantValue(KnownTypeReference.String, xml));
targetCollection.Add(interningProvider.Intern(attr));
}
}
[Serializable, FastSerializerVersion(cecilLoaderVersion)]
sealed class UnresolvedSecurityDeclaration : ISupportsInterning
{
IConstantValue securityAction;
byte[] blob;
readonly IConstantValue securityAction;
readonly byte[] blob;
public UnresolvedSecurityDeclaration(IConstantValue securityAction, byte[] blob)
{
@ -1444,11 +1454,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1444,11 +1454,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
}
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
securityAction = provider.Intern(securityAction);
}
int ISupportsInterning.GetHashCodeForInterning()
{
return securityAction.GetHashCode() ^ GetBlobHashCode(blob);
@ -1462,7 +1467,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1462,7 +1467,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
}
[Serializable, FastSerializerVersion(cecilLoaderVersion)]
sealed class UnresolvedSecurityAttribute : IUnresolvedAttribute
sealed class UnresolvedSecurityAttribute : IUnresolvedAttribute, ISupportsInterning
{
readonly UnresolvedSecurityDeclaration secDecl;
readonly int index;
@ -1482,6 +1487,17 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1482,6 +1487,17 @@ namespace ICSharpCode.NRefactory.TypeSystem
{
return secDecl.Resolve(context.CurrentAssembly)[index];
}
int ISupportsInterning.GetHashCodeForInterning()
{
return index ^ secDecl.GetHashCode();
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
UnresolvedSecurityAttribute attr = other as UnresolvedSecurityAttribute;
return attr != null && index == attr.index && secDecl == attr.secDecl;
}
}
#endregion
#endregion
@ -1511,7 +1527,9 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1511,7 +1527,9 @@ namespace ICSharpCode.NRefactory.TypeSystem
void InitTypeParameterConstraints(TypeDefinition typeDefinition, IList<IUnresolvedTypeParameter> typeParameters)
{
for (int i = 0; i < typeParameters.Count; i++) {
AddConstraints((DefaultUnresolvedTypeParameter)typeParameters[i], typeDefinition.GenericParameters[i]);
var tp = (DefaultUnresolvedTypeParameter)typeParameters[i];
AddConstraints(tp, typeDefinition.GenericParameters[i]);
tp.ApplyInterningProvider(interningProvider);
}
}
@ -1530,9 +1548,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1530,9 +1548,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
td.AddDefaultConstructorIfRequired = (td.Kind == TypeKind.Struct || td.Kind == TypeKind.Enum);
InitMembers(typeDefinition, td, td.Members);
if (this.InterningProvider != null) {
td.ApplyInterningProvider(this.InterningProvider);
}
td.ApplyInterningProvider(interningProvider);
td.Freeze();
RegisterCecilObject(td, typeDefinition);
}
@ -1750,9 +1766,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1750,9 +1766,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
loader.AddAttributes(typeDefinition, this);
flags[FlagHasExtensionMethods] = HasExtensionAttribute(typeDefinition);
if (loader.InterningProvider != null) {
this.ApplyInterningProvider(loader.InterningProvider);
}
this.ApplyInterningProvider(loader.interningProvider);
this.Freeze();
}
@ -1895,7 +1909,9 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1895,7 +1909,9 @@ namespace ICSharpCode.NRefactory.TypeSystem
EntityType.Method, i, method.GenericParameters[i].Name));
}
for (int i = 0; i < method.GenericParameters.Count; i++) {
AddConstraints((DefaultUnresolvedTypeParameter)m.TypeParameters[i], method.GenericParameters[i]);
var tp = (DefaultUnresolvedTypeParameter)m.TypeParameters[i];
AddConstraints(tp, method.GenericParameters[i]);
tp.ApplyInterningProvider(interningProvider);
}
}
@ -2005,7 +2021,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -2005,7 +2021,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
if (parameter == null)
throw new ArgumentNullException("parameter");
var type = ReadTypeReference(parameter.ParameterType, typeAttributes: parameter);
var p = new DefaultUnresolvedParameter(type, parameter.Name);
var p = new DefaultUnresolvedParameter(type, interningProvider.Intern(parameter.Name));
if (parameter.ParameterType is Mono.Cecil.ByReferenceType) {
if (!parameter.IsIn && parameter.IsOut)
@ -2016,7 +2032,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -2016,7 +2032,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
AddAttributes(parameter, p);
if (parameter.IsOptional) {
p.DefaultValue = new SimpleConstantValue(type, parameter.Constant);
p.DefaultValue = CreateSimpleConstantValue(type, parameter.Constant);
}
if (parameter.ParameterType is Mono.Cecil.ArrayType) {
@ -2028,7 +2044,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -2028,7 +2044,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
}
}
return p;
return interningProvider.Intern(p);
}
#endregion
@ -2056,7 +2072,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -2056,7 +2072,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
f.IsStatic = field.IsStatic;
f.ReturnType = ReadTypeReference(field.FieldType, typeAttributes: field);
if (field.HasConstant) {
f.ConstantValue = new SimpleConstantValue(f.ReturnType, field.Constant);
f.ConstantValue = CreateSimpleConstantValue(f.ReturnType, field.Constant);
}
AddAttributes(field, f);
@ -2184,13 +2200,14 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -2184,13 +2200,14 @@ namespace ICSharpCode.NRefactory.TypeSystem
}
#endregion
#region FinishReadMember / Interning
void FinishReadMember(AbstractUnresolvedMember member, MemberReference cecilDefinition)
{
if (this.InterningProvider != null)
member.ApplyInterningProvider(this.InterningProvider);
member.ApplyInterningProvider(interningProvider);
member.Freeze();
RegisterCecilObject(member, cecilDefinition);
}
#endregion
#region Type system translation table
readonly Dictionary<object, object> typeSystemTranslationTable;

60
ICSharpCode.NRefactory/TypeSystem/IInterningProvider.cs

@ -39,16 +39,64 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -39,16 +39,64 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// 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.
/// </remarks>
public interface IInterningProvider
public abstract class InterningProvider
{
public static readonly InterningProvider Dummy = new DummyInterningProvider();
/// <summary>
/// Interns the specified object.
/// The object must implement <see cref="ISupportsInterning"/>, or must be of one of the types
/// known to the interning provider to use value equality,
/// otherwise it will be returned without being interned.
///
/// If the object is freezable, it will be frozen.
/// </summary>
public abstract ISupportsInterning Intern(ISupportsInterning obj);
/// <summary>
/// Interns the specified object.
///
/// If the object is freezable, it will be frozen.
/// </summary>
public T Intern<T>(T obj) where T : class, ISupportsInterning
{
ISupportsInterning input = obj;
return (T)Intern(input);
}
/// <summary>
/// Interns the specified string.
/// </summary>
public abstract string Intern(string text);
/// <summary>
/// Inters a boxed value type.
/// </summary>
public abstract object InternValue(object obj);
/// <summary>
/// Interns the given list. Uses reference equality to compare the list elements.
/// </summary>
T Intern<T>(T obj) where T : class;
public abstract IList<T> InternList<T>(IList<T> list) where T : class;
IList<T> InternList<T>(IList<T> list) where T : class;
sealed class DummyInterningProvider : InterningProvider
{
public override ISupportsInterning Intern(ISupportsInterning obj)
{
return obj;
}
public override string Intern(string text)
{
return text;
}
public override object InternValue(object obj)
{
return obj;
}
public override IList<T> InternList<T>(IList<T> list)
{
return list;
}
}
}
}

5
ICSharpCode.NRefactory/TypeSystem/ISupportsInterning.cs

@ -26,11 +26,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -26,11 +26,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// </summary>
public interface ISupportsInterning
{
/// <summary>
/// Interns child objects and strings.
/// </summary>
void PrepareForInterning(IInterningProvider provider);
/// <summary>
/// Gets a hash code for interning.
/// </summary>

2
ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractResolvedTypeParameter.cs

@ -219,7 +219,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -219,7 +219,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public ITypeReference ToTypeReference()
{
return new TypeParameterReference(this.OwnerType, this.Index);
return TypeParameterReference.Create(this.OwnerType, this.Index);
}
IEnumerable<IType> IType.GetNestedTypes(Predicate<ITypeDefinition> filter, GetMemberOptions options)

10
ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractUnresolvedEntity.cs

@ -85,7 +85,13 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -85,7 +85,13 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
rareFields.FreezeInternal();
}
public virtual void ApplyInterningProvider(IInterningProvider provider)
/// <summary>
/// Uses the specified interning provider to intern
/// strings and lists in this entity.
/// This method does not test arbitrary objects to see if they implement ISupportsInterning;
/// instead we assume that those are interned immediately when they are created (before they are added to this entity).
/// </summary>
public virtual void ApplyInterningProvider(InterningProvider provider)
{
if (provider == null)
throw new ArgumentNullException("provider");
@ -124,7 +130,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -124,7 +130,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
}
public virtual void ApplyInterningProvider(IInterningProvider provider)
public virtual void ApplyInterningProvider(InterningProvider provider)
{
}

3
ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractUnresolvedMember.cs

@ -32,10 +32,9 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -32,10 +32,9 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
ITypeReference returnType = SpecialType.UnknownType;
IList<IMemberReference> interfaceImplementations;
public override void ApplyInterningProvider(IInterningProvider provider)
public override void ApplyInterningProvider(InterningProvider provider)
{
base.ApplyInterningProvider(provider);
returnType = provider.Intern(returnType);
interfaceImplementations = provider.InternList(interfaceImplementations);
}

7
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAssemblyReference.cs

@ -29,7 +29,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -29,7 +29,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public static readonly IAssemblyReference CurrentAssembly = new CurrentAssemblyReference();
public static readonly IAssemblyReference Corlib = new DefaultAssemblyReference("mscorlib");
string shortName;
readonly string shortName;
public DefaultAssemblyReference(string assemblyName)
{
@ -57,11 +57,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -57,11 +57,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return shortName;
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
shortName = provider.Intern(shortName);
}
int ISupportsInterning.GetHashCodeForInterning()
{
unchecked {

17
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultMemberReference.cs

@ -33,11 +33,11 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -33,11 +33,11 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
[Serializable]
public sealed class DefaultMemberReference : IMemberReference, ISupportsInterning
{
EntityType entityType;
ITypeReference typeReference;
string name;
int typeParameterCount;
IList<ITypeReference> parameterTypes;
readonly EntityType entityType;
readonly ITypeReference typeReference;
readonly string name;
readonly int typeParameterCount;
readonly IList<ITypeReference> parameterTypes;
public DefaultMemberReference(EntityType entityType, ITypeReference typeReference, string name, int typeParameterCount = 0, IList<ITypeReference> parameterTypes = null)
{
@ -99,13 +99,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -99,13 +99,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return null;
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
typeReference = provider.Intern(typeReference);
name = provider.Intern(name);
parameterTypes = provider.InternList(parameterTypes);
}
int ISupportsInterning.GetHashCodeForInterning()
{
return (int)entityType ^ typeReference.GetHashCode() ^ name.GetHashCode() ^ parameterTypes.GetHashCode();

68
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedAttribute.cs

@ -106,11 +106,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -106,11 +106,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
));
}
public void AddNamedFieldArgument(string fieldName, ITypeReference valueType, object value)
{
AddNamedFieldArgument(fieldName, new SimpleConstantValue(valueType, value));
}
public void AddNamedPropertyArgument(string propertyName, IConstantValue value)
{
this.NamedArguments.Add(new KeyValuePair<IMemberReference, IConstantValue>(
@ -119,40 +114,29 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -119,40 +114,29 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
));
}
public void AddNamedPropertyArgument(string propertyName, ITypeReference valueType, object value)
{
AddNamedPropertyArgument(propertyName, new SimpleConstantValue(valueType, value));
}
public IAttribute CreateResolvedAttribute(ITypeResolveContext context)
{
return new DefaultResolvedAttribute(this, context);
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
int ISupportsInterning.GetHashCodeForInterning()
{
if (!this.IsFrozen) {
attributeType = provider.Intern(attributeType);
constructorParameterTypes = provider.InternList(constructorParameterTypes);
positionalArguments = provider.InternList(positionalArguments);
if (namedArguments != null) {
for (int i = 0; i < namedArguments.Count; i++) {
namedArguments[i] = new KeyValuePair<IMemberReference, IConstantValue>(
provider.Intern(namedArguments[i].Key),
provider.Intern(namedArguments[i].Value)
);
int hash = attributeType.GetHashCode() ^ constructorParameterTypes.GetHashCode();
unchecked {
if (constructorParameterTypes != null) {
foreach (var type in constructorParameterTypes) {
hash *= 27;
hash += type.GetHashCode();
}
}
Freeze();
}
}
int ISupportsInterning.GetHashCodeForInterning()
{
int hash = attributeType.GetHashCode() ^ constructorParameterTypes.GetHashCode() ^ positionalArguments.GetHashCode();
if (namedArguments != null) {
foreach (var pair in namedArguments) {
unchecked {
if (positionalArguments != null) {
foreach (var arg in positionalArguments) {
hash *= 31;
hash += arg.GetHashCode();
}
}
if (namedArguments != null) {
foreach (var pair in namedArguments) {
hash *= 71;
hash += pair.Key.GetHashCode() + pair.Value.GetHashCode() * 73;
}
@ -165,13 +149,33 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -165,13 +149,33 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
DefaultUnresolvedAttribute o = other as DefaultUnresolvedAttribute;
return o != null && attributeType == o.attributeType
&& constructorParameterTypes == o.constructorParameterTypes && positionalArguments == o.positionalArguments
&& ListEquals(constructorParameterTypes, o.constructorParameterTypes)
&& ListEquals(positionalArguments, o.positionalArguments)
&& ListEquals(namedArguments ?? EmptyList<KeyValuePair<IMemberReference, IConstantValue>>.Instance,
o.namedArguments ?? EmptyList<KeyValuePair<IMemberReference, IConstantValue>>.Instance);
}
static bool ListEquals<T>(IList<T> list1, IList<T> list2) where T : class
{
if (list1 == null)
list1 = EmptyList<T>.Instance;
if (list2 == null)
list2 = EmptyList<T>.Instance;
if (list1 == list2)
return true;
if (list1.Count != list2.Count)
return false;
for (int i = 0; i < list1.Count; i++) {
if (list1[i] != list2[i])
return false;
}
return true;
}
static bool ListEquals(IList<KeyValuePair<IMemberReference, IConstantValue>> list1, IList<KeyValuePair<IMemberReference, IConstantValue>> list2)
{
if (list1 == list2)
return true;
if (list1.Count != list2.Count)
return false;
for (int i = 0; i < list1.Count; i++) {

8
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedEvent.cs

@ -36,14 +36,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -36,14 +36,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
FreezableHelper.Freeze(invokeAccessor);
}
public override void ApplyInterningProvider(IInterningProvider provider)
{
base.ApplyInterningProvider(provider);
addAccessor = provider.Intern(addAccessor);
removeAccessor = provider.Intern(removeAccessor);
invokeAccessor = provider.Intern(invokeAccessor);
}
public DefaultUnresolvedEvent()
{
this.EntityType = EntityType.Event;

6
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedField.cs

@ -34,12 +34,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -34,12 +34,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
base.FreezeInternal();
}
public override void ApplyInterningProvider(IInterningProvider provider)
{
base.ApplyInterningProvider(provider);
constantValue = provider.Intern(constantValue);
}
public DefaultUnresolvedField()
{
this.EntityType = EntityType.Field;

2
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedMethod.cs

@ -54,7 +54,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -54,7 +54,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return copy;
}
public override void ApplyInterningProvider(IInterningProvider provider)
public override void ApplyInterningProvider(InterningProvider provider)
{
base.ApplyInterningProvider(provider);
if (provider != null) {

33
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedParameter.cs

@ -18,8 +18,8 @@ @@ -18,8 +18,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.Utils;
@ -146,29 +146,30 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -146,29 +146,30 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
get { return this.DefaultValue != null; }
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
int ISupportsInterning.GetHashCodeForInterning()
{
if (!IsFrozen) {
name = provider.Intern(name);
type = provider.Intern(type);
attributes = provider.InternList(attributes);
defaultValue = provider.Intern(defaultValue);
unchecked {
int hashCode = 1919191 ^ (flags & ~1);
hashCode *= 31;
hashCode += type.GetHashCode();
hashCode *= 31;
hashCode += name.GetHashCode();
hashCode += attributes != null ? attributes.Count : 0;
return hashCode;
}
}
int ISupportsInterning.GetHashCodeForInterning()
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
return type.GetHashCode() ^ name.GetHashCode()
^ (attributes != null ? attributes.GetHashCode() : 0)
^ (defaultValue != null ? defaultValue.GetHashCode() : 0)
^ region.GetHashCode() ^ flags;
// compare everything except for the IsFrozen flag
DefaultUnresolvedParameter p = other as DefaultUnresolvedParameter;
return p != null && type == p.type && name == p.name && ListEquals(attributes, p.attributes)
&& defaultValue == p.defaultValue && region == p.region && (flags & ~1) == (p.flags & ~1);
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
static bool ListEquals(IList<IUnresolvedAttribute> list1, IList<IUnresolvedAttribute> list2)
{
DefaultUnresolvedParameter p = other as DefaultUnresolvedParameter;
return p != null && type == p.type && attributes == p.attributes && name == p.name
&& defaultValue == p.defaultValue && region == p.region && flags == p.flags;
return (list1 ?? EmptyList<IUnresolvedAttribute>.Instance).SequenceEqual(list2 ?? EmptyList<IUnresolvedAttribute>.Instance);
}
public override string ToString()

4
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedProperty.cs

@ -47,11 +47,9 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -47,11 +47,9 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return copy;
}
public override void ApplyInterningProvider(IInterningProvider provider)
public override void ApplyInterningProvider(InterningProvider provider)
{
base.ApplyInterningProvider(provider);
getter = provider.Intern(getter);
setter = provider.Intern(setter);
parameters = provider.InternList(parameters);
}

16
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedTypeParameter.cs

@ -157,6 +157,22 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -157,6 +157,22 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
}
}
/// <summary>
/// Uses the specified interning provider to intern
/// strings and lists in this entity.
/// This method does not test arbitrary objects to see if they implement ISupportsInterning;
/// instead we assume that those are interned immediately when they are created (before they are added to this entity).
/// </summary>
public virtual void ApplyInterningProvider(InterningProvider provider)
{
if (provider == null)
throw new ArgumentNullException("provider");
FreezableHelper.ThrowIfFrozen(this);
name = provider.Intern(name);
attributes = provider.InternList(attributes);
constraints = provider.InternList(constraints);
}
public virtual ITypeParameter CreateResolvedTypeParameter(ITypeResolveContext context)
{
IEntity owner = null;

2
ICSharpCode.NRefactory/TypeSystem/Implementation/DummyTypeParameter.cs

@ -153,7 +153,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -153,7 +153,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public override ITypeReference ToTypeReference()
{
return new TypeParameterReference(ownerType, index);
return TypeParameterReference.Create(ownerType, index);
}
public override IType AcceptVisitor(TypeVisitor visitor)

13
ICSharpCode.NRefactory/TypeSystem/Implementation/GetClassTypeReference.cs

@ -27,9 +27,9 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -27,9 +27,9 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
[Serializable]
public sealed class GetClassTypeReference : ITypeReference, ISupportsInterning
{
IAssemblyReference assembly;
string nameSpace, name;
int typeParameterCount;
readonly IAssemblyReference assembly;
readonly string nameSpace, name;
readonly int typeParameterCount;
/// <summary>
/// Creates a new GetClassTypeReference that searches a top-level type.
@ -115,13 +115,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -115,13 +115,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return name1 + "." + name2;
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
assembly = provider.Intern(assembly);
nameSpace = provider.Intern(nameSpace);
name = provider.Intern(name);
}
int ISupportsInterning.GetHashCodeForInterning()
{
unchecked {

12
ICSharpCode.NRefactory/TypeSystem/Implementation/NestedTypeReference.cs

@ -26,9 +26,9 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -26,9 +26,9 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
[Serializable]
public sealed class NestedTypeReference : ITypeReference, ISupportsInterning
{
ITypeReference declaringTypeRef;
string name;
int additionalTypeParameterCount;
readonly ITypeReference declaringTypeRef;
readonly string name;
readonly int additionalTypeParameterCount;
/// <summary>
/// Creates a new NestedTypeReference.
@ -84,12 +84,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -84,12 +84,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return declaringTypeRef + "+" + name + "`" + additionalTypeParameterCount;
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
declaringTypeRef = provider.Intern(declaringTypeRef);
name = provider.Intern(name);
}
int ISupportsInterning.GetHashCodeForInterning()
{
return declaringTypeRef.GetHashCode() ^ name.GetHashCode() ^ additionalTypeParameterCount;

10
ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleConstantValue.cs

@ -27,8 +27,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -27,8 +27,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
[Serializable]
public sealed class SimpleConstantValue : IConstantValue, ISupportsInterning
{
ITypeReference type;
object value;
readonly ITypeReference type;
readonly object value;
public SimpleConstantValue(ITypeReference type, object value)
{
@ -55,12 +55,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -55,12 +55,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return value.ToString();
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
type = provider.Intern(type);
value = provider.Intern(value);
}
int ISupportsInterning.GetHashCodeForInterning()
{
return type.GetHashCode() ^ (value != null ? value.GetHashCode() : 0);

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

@ -30,7 +30,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -30,7 +30,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
/// <summary>
/// Simple interning provider.
/// </summary>
public sealed class SimpleInterningProvider : IInterningProvider
public sealed class SimpleInterningProvider : InterningProvider
{
sealed class InterningComparer : IEqualityComparer<ISupportsInterning>
{
@ -82,52 +82,52 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -82,52 +82,52 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
Dictionary<ISupportsInterning, ISupportsInterning> supportsInternDict = new Dictionary<ISupportsInterning, ISupportsInterning>(new InterningComparer());
Dictionary<IEnumerable, IEnumerable> listDict = new Dictionary<IEnumerable, IEnumerable>(new ListComparer());
int stackDepth = 0;
public T Intern<T>(T obj) where T : class
public override ISupportsInterning Intern(ISupportsInterning obj)
{
if (obj == null)
return null;
ISupportsInterning s = obj as ISupportsInterning;
if (s != null) {
ISupportsInterning output;
//if (supportsInternDict.TryGetValue(s, out output)) {
// obj = (T)output;
//} else {
s.PrepareForInterning(this);
if (supportsInternDict.TryGetValue(s, out output))
obj = (T)output;
else
supportsInternDict.Add(s, s);
//}
} else if (Type.GetTypeCode(obj.GetType()) >= TypeCode.Boolean) {
// Intern primitive types (and strings) by value
object output;
if (byValueDict.TryGetValue(obj, out output))
obj = (T)output;
else
byValueDict.Add(obj, obj);
ISupportsInterning output;
if (supportsInternDict.TryGetValue(obj, out output)) {
return output;
} else {
// ensure objects are frozen when we put them into the dictionary
FreezableHelper.Freeze(obj);
supportsInternDict.Add(obj, obj);
return obj;
}
stackDepth--;
return obj;
}
public IList<T> InternList<T>(IList<T> list) where T : class
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;
for (int i = 0; i < list.Count; i++) {
T oldItem = list[i];
T newItem = Intern(oldItem);
if (oldItem != newItem) {
if (list.IsReadOnly) {
T[] array = new T[list.Count];
list.CopyTo(array, 0);
list = array;
}
list[i] = newItem;
}
}
if (list.Count == 0)
return EmptyList<T>.Instance;
if (!list.IsReadOnly)
list = new ReadOnlyCollection<T>(list);
IEnumerable output;

39
ICSharpCode.NRefactory/TypeSystem/Implementation/TypeParameterReference.cs

@ -18,12 +18,34 @@ @@ -18,12 +18,34 @@
using System;
using System.Globalization;
using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
[Serializable]
public sealed class TypeParameterReference : ITypeReference, ISupportsInterning
public sealed class TypeParameterReference : ITypeReference
{
static readonly TypeParameterReference[] classTypeParameterReferences = new TypeParameterReference[8];
static readonly TypeParameterReference[] methodTypeParameterReferences = new TypeParameterReference[8];
/// <summary>
/// Creates a type parameter reference.
/// For common type parameter references, this method may return a shared instance.
/// </summary>
public static TypeParameterReference Create(EntityType ownerType, int index)
{
if (index >= 0 && index < 8 && (ownerType == EntityType.TypeDefinition || ownerType == EntityType.Method)) {
TypeParameterReference[] arr = (ownerType == EntityType.TypeDefinition) ? classTypeParameterReferences : methodTypeParameterReferences;
TypeParameterReference result = LazyInit.VolatileRead(ref arr[index]);
if (result == null) {
result = LazyInit.GetOrSet(ref arr[index], new TypeParameterReference(ownerType, index));
}
return result;
} else {
return new TypeParameterReference(ownerType, index);
}
}
readonly EntityType ownerType;
readonly int index;
@ -52,21 +74,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -52,21 +74,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
}
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
}
int ISupportsInterning.GetHashCodeForInterning()
{
return index * 33 + (int)ownerType;
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
TypeParameterReference r = other as TypeParameterReference;
return r != null && index == r.index && ownerType == r.ownerType;
}
public override string ToString()
{
if (ownerType == EntityType.Method)

2
ICSharpCode.NRefactory/TypeSystem/NullableType.cs

@ -78,7 +78,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -78,7 +78,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// <summary>
/// Creates a nullable type reference.
/// </summary>
public static ITypeReference Create(ITypeReference elementType)
public static ParameterizedTypeReference Create(ITypeReference elementType)
{
if (elementType == null)
throw new ArgumentNullException("elementType");

12
ICSharpCode.NRefactory/TypeSystem/ParameterizedType.cs

@ -341,8 +341,8 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -341,8 +341,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
[Serializable]
public sealed class ParameterizedTypeReference : ITypeReference, ISupportsInterning
{
ITypeReference genericType;
ITypeReference[] typeArguments;
readonly ITypeReference genericType;
readonly ITypeReference[] typeArguments;
public ParameterizedTypeReference(ITypeReference genericType, IEnumerable<ITypeReference> typeArguments)
{
@ -402,14 +402,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -402,14 +402,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
return b.ToString();
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
genericType = provider.Intern(genericType);
for (int i = 0; i < typeArguments.Length; i++) {
typeArguments[i] = provider.Intern(typeArguments[i]);
}
}
int ISupportsInterning.GetHashCodeForInterning()
{
int hashCode = genericType.GetHashCode();

7
ICSharpCode.NRefactory/TypeSystem/PointerType.cs

@ -76,7 +76,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -76,7 +76,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
[Serializable]
public sealed class PointerTypeReference : ITypeReference, ISupportsInterning
{
ITypeReference elementType;
readonly ITypeReference elementType;
public PointerTypeReference(ITypeReference elementType)
{
@ -99,11 +99,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -99,11 +99,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
return elementType.ToString() + "*";
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
elementType = provider.Intern(elementType);
}
int ISupportsInterning.GetHashCodeForInterning()
{
return elementType.GetHashCode() ^ 91725812;

8
ICSharpCode.NRefactory/TypeSystem/ReflectionHelper.cs

@ -106,9 +106,9 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -106,9 +106,9 @@ namespace ICSharpCode.NRefactory.TypeSystem
return new ByReferenceTypeReference(ToTypeReference(type.GetElementType()));
} else if (type.IsGenericParameter) {
if (type.DeclaringMethod != null) {
return new TypeParameterReference(EntityType.Method, type.GenericParameterPosition);
return TypeParameterReference.Create(EntityType.Method, type.GenericParameterPosition);
} else {
return new TypeParameterReference(EntityType.TypeDefinition, type.GenericParameterPosition);
return TypeParameterReference.Create(EntityType.TypeDefinition, type.GenericParameterPosition);
}
} else if (type.DeclaringType != null) {
if (type == typeof(Dynamic))
@ -259,11 +259,11 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -259,11 +259,11 @@ namespace ICSharpCode.NRefactory.TypeSystem
// method type parameter reference
pos++;
int index = ReadTypeParameterCount(reflectionTypeName, ref pos);
reference = new TypeParameterReference(EntityType.Method, index);
reference = TypeParameterReference.Create(EntityType.Method, index);
} else {
// class type parameter reference
int index = ReadTypeParameterCount(reflectionTypeName, ref pos);
reference = new TypeParameterReference(EntityType.TypeDefinition, index);
reference = TypeParameterReference.Create(EntityType.TypeDefinition, index);
}
} else {
// not a type parameter reference: read the actual type name

Loading…
Cancel
Save