From d63a37dcdaf44b524f057e69f15f47d3b3b959db Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Wed, 11 Jul 2018 22:20:58 +0200 Subject: [PATCH] Allow comparing metadata entities across compilations. --- .../Implementation/MetadataEvent.cs | 15 ++++++- .../Implementation/MetadataField.cs | 17 ++++++- .../Implementation/MetadataMethod.cs | 15 ++++++- .../Implementation/MetadataProperty.cs | 44 ++++++++++++------- .../Implementation/MetadataTypeDefinition.cs | 15 ++++++- .../Implementation/MetadataTypeParameter.cs | 10 +++++ ILSpy/Controls/CustomDialog.cs | 5 --- 7 files changed, 96 insertions(+), 25 deletions(-) diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataEvent.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataEvent.cs index f7ed937b2..674dad4cc 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataEvent.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataEvent.cs @@ -127,9 +127,22 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation public string ReflectionName => $"{DeclaringType?.ReflectionName}.{Name}"; public string Namespace => DeclaringType?.Namespace ?? string.Empty; + public override bool Equals(object obj) + { + if (obj is MetadataEvent ev) { + return handle == ev.handle && assembly.PEFile == ev.assembly.PEFile; + } + return false; + } + + public override int GetHashCode() + { + return 0x7937039a ^ assembly.PEFile.GetHashCode() ^ handle.GetHashCode(); + } + bool IMember.Equals(IMember obj, TypeVisitor typeNormalization) { - return this == obj; + return Equals(obj); } public IMember Specialize(TypeParameterSubstitution substitution) diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataField.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataField.cs index b02f947ca..e5dacfb4b 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataField.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataField.cs @@ -255,9 +255,22 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation return null; } - public bool Equals(IMember obj, TypeVisitor typeNormalization) + public override bool Equals(object obj) { - return this == obj; + if (obj is MetadataField f) { + return handle == f.handle && assembly.PEFile == f.assembly.PEFile; + } + return false; + } + + public override int GetHashCode() + { + return 0x11dda32b ^ assembly.PEFile.GetHashCode() ^ handle.GetHashCode(); + } + + bool IMember.Equals(IMember obj, TypeVisitor typeNormalization) + { + return Equals(obj); } public IMember Specialize(TypeParameterSubstitution substitution) diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs index 07101b7e3..f3e3b43ce 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs @@ -406,9 +406,22 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation public string ReflectionName => $"{DeclaringType?.ReflectionName}.{Name}"; public string Namespace => DeclaringType?.Namespace ?? string.Empty; + public override bool Equals(object obj) + { + if (obj is MetadataMethod m) { + return handle == m.handle && assembly.PEFile == m.assembly.PEFile; + } + return false; + } + + public override int GetHashCode() + { + return 0x5a00d671 ^ assembly.PEFile.GetHashCode() ^ handle.GetHashCode(); + } + bool IMember.Equals(IMember obj, TypeVisitor typeNormalization) { - return obj == this; + return Equals(obj); } public IMethod Specialize(TypeParameterSubstitution substitution) diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataProperty.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataProperty.cs index d2612bd29..7817b301c 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataProperty.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataProperty.cs @@ -36,8 +36,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation readonly MetadataAssembly assembly; readonly PropertyDefinitionHandle propertyHandle; - readonly MethodDefinitionHandle getterHandle; - readonly MethodDefinitionHandle setterHandle; + readonly IMethod getter; + readonly IMethod setter; readonly string name; readonly SymbolKind symbolKind; @@ -56,8 +56,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation var metadata = assembly.metadata; var prop = metadata.GetPropertyDefinition(handle); var accessors = prop.GetAccessors(); - getterHandle = accessors.Getter; - setterHandle = accessors.Setter; + getter = assembly.GetDefinition(accessors.Getter); + setter = assembly.GetDefinition(accessors.Setter); name = metadata.GetString(prop.Name); if (name == (DeclaringTypeDefinition as MetadataTypeDefinition)?.DefaultMemberName) { symbolKind = SymbolKind.Indexer; @@ -78,12 +78,12 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation public EntityHandle MetadataToken => propertyHandle; public string Name => name; - public bool CanGet => !getterHandle.IsNil; - public bool CanSet => !setterHandle.IsNil; + public bool CanGet => getter != null; + public bool CanSet => setter != null; - public IMethod Getter => assembly.GetDefinition(getterHandle); - public IMethod Setter => assembly.GetDefinition(setterHandle); - IMethod AnyAccessor => assembly.GetDefinition(getterHandle.IsNil ? setterHandle : getterHandle); + public IMethod Getter => getter; + public IMethod Setter => setter; + IMethod AnyAccessor => getter ?? setter; public bool IsIndexer => symbolKind == SymbolKind.Indexer; public SymbolKind SymbolKind => symbolKind; @@ -114,11 +114,12 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation var propertyDef = assembly.metadata.GetPropertyDefinition(propertyHandle); var genericContext = new GenericContext(DeclaringType.TypeParameters); var signature = propertyDef.DecodeSignature(assembly.TypeProvider, genericContext); + var accessors = propertyDef.GetAccessors(); ParameterHandleCollection? parameterHandles; - if (!getterHandle.IsNil) - parameterHandles = assembly.metadata.GetMethodDefinition(getterHandle).GetParameters(); - else if (!setterHandle.IsNil) - parameterHandles = assembly.metadata.GetMethodDefinition(setterHandle).GetParameters(); + if (!accessors.Getter.IsNil) + parameterHandles = assembly.metadata.GetMethodDefinition(accessors.Getter).GetParameters(); + else if (!accessors.Setter.IsNil) + parameterHandles = assembly.metadata.GetMethodDefinition(accessors.Setter).GetParameters(); else parameterHandles = null; var (returnType, parameters) = MetadataMethod.DecodeSignature(assembly, this, signature, parameterHandles); @@ -169,7 +170,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation Accessibility ComputeAccessibility() { - if (IsOverride && (getterHandle.IsNil || setterHandle.IsNil)) { + if (IsOverride && (getter == null || setter == null)) { foreach (var baseMember in InheritanceHelper.GetBaseMembers(this, includeImplementedInterfaces: false)) { if (!baseMember.IsOverride) return baseMember.Accessibility; @@ -219,9 +220,22 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation public string ReflectionName => $"{DeclaringType?.ReflectionName}.{Name}"; public string Namespace => DeclaringType?.Namespace ?? string.Empty; + public override bool Equals(object obj) + { + if (obj is MetadataProperty p) { + return propertyHandle == p.propertyHandle && assembly.PEFile == p.assembly.PEFile; + } + return false; + } + + public override int GetHashCode() + { + return 0x32b6a76c ^ assembly.PEFile.GetHashCode() ^ propertyHandle.GetHashCode(); + } + bool IMember.Equals(IMember obj, TypeVisitor typeNormalization) { - return this == obj; + return Equals(obj); } public IMember Specialize(TypeParameterSubstitution substitution) diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs index 56579b3e7..b9c581536 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs @@ -422,9 +422,22 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation return this; } + public override bool Equals(object obj) + { + if (obj is MetadataTypeDefinition td) { + return handle == td.handle && assembly.PEFile == td.assembly.PEFile; + } + return false; + } + + public override int GetHashCode() + { + return 0x2e0520f2 ^ assembly.PEFile.GetHashCode() ^ handle.GetHashCode(); + } + bool IEquatable.Equals(IType other) { - return this == other; + return Equals(other); } #region GetNestedTypes diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeParameter.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeParameter.cs index 624f1e0fc..f0cf7326d 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeParameter.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeParameter.cs @@ -143,6 +143,16 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation return result; } + public override int GetHashCode() + { + return 0x51fc5b83 ^ assembly.PEFile.GetHashCode() ^ handle.GetHashCode(); + } + + public override bool Equals(IType other) + { + return other is MetadataTypeParameter tp && handle == tp.handle && assembly.PEFile == tp.assembly.PEFile; + } + public override string ToString() { return $"{MetadataTokens.GetToken(handle):X8} Index={Index} Owner={Owner}"; diff --git a/ILSpy/Controls/CustomDialog.cs b/ILSpy/Controls/CustomDialog.cs index 445c5655b..6150d2e69 100644 --- a/ILSpy/Controls/CustomDialog.cs +++ b/ILSpy/Controls/CustomDialog.cs @@ -158,10 +158,5 @@ namespace ICSharpCode.ILSpy.Controls this.AutoScaleMode = AutoScaleMode.Dpi; this.AutoScaleDimensions = new SizeF(96, 96); } - - private void CustomDialog_KeyDown(object sender, KeyEventArgs e) - { - throw new NotImplementedException(); - } } }