From f9b2fe37eebb7e236590b2f904afe1093037ba67 Mon Sep 17 00:00:00 2001 From: Manuel Carrasco Date: Sun, 6 Oct 2019 19:05:16 -0300 Subject: [PATCH 01/14] Added Constraints set to GenericParameter class. --- CCIProvider/TypeExtractor.cs | 3 ++- MetadataProvider/AssemblyExtractor.cs | 6 +++++- Model/Types/Types.cs | 6 ++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CCIProvider/TypeExtractor.cs b/CCIProvider/TypeExtractor.cs index 19e64dda..39e813c8 100644 --- a/CCIProvider/TypeExtractor.cs +++ b/CCIProvider/TypeExtractor.cs @@ -818,7 +818,8 @@ private void ExtractGenericTypeParameters(IGenericDefinition definingType, Cci.I definingType.GenericParameters.Add(parameter); defGenericContext.TypeParameters.Add(parameter); - } + parameter.Constraints.AddRange(parameterdef.Constraints.Select(cciTypeRef => ExtractType(cciTypeRef))); + } } private static IList GetAllGenericTypeParameters(Cci.ITypeDefinition typedef) diff --git a/MetadataProvider/AssemblyExtractor.cs b/MetadataProvider/AssemblyExtractor.cs index 66787d90..9b7ec757 100644 --- a/MetadataProvider/AssemblyExtractor.cs +++ b/MetadataProvider/AssemblyExtractor.cs @@ -459,7 +459,11 @@ private void ExtractGenericParameter(GenericParameterKind parameterKind, IGeneri } genericContainer.GenericParameters.Add(genericParameter); - } + var constraints = genericParameterdef.GetConstraints().Select( + constraint => signatureTypeProvider.GetTypeFromHandle(metadata, defGenericContext, metadata.GetGenericParameterConstraint(constraint).Type + )); + genericParameter.Constraints.AddRange(constraints); + } private void ExtractField(SRM.FieldDefinitionHandle handle) { diff --git a/Model/Types/Types.cs b/Model/Types/Types.cs index 0d6934db..8999b4e9 100644 --- a/Model/Types/Types.cs +++ b/Model/Types/Types.cs @@ -539,7 +539,8 @@ private static string GetName(GenericParameterKind kind, ushort index) public class GenericParameter : IGenericParameterReference { public ISet Attributes { get; private set; } - public TypeKind TypeKind { get; set; } + public ISet Constraints { get; private set; } + public TypeKind TypeKind { get; set; } public IGenericDefinition GenericContainer { get; set; } public GenericParameterKind Kind { get; set; } public ushort Index { get; set; } @@ -552,7 +553,8 @@ public GenericParameter(GenericParameterKind kind, ushort index, string name, Ty this.Name = name; this.TypeKind = typeKind; this.Attributes = new HashSet(); - } + this.Constraints = new HashSet(); + } #region IGenericParameterReference members From 853d63fb87eaad6dd30cbc0577f8c0f6166c54bd Mon Sep 17 00:00:00 2001 From: fcurdi Date: Thu, 19 Mar 2020 19:51:14 -0300 Subject: [PATCH 02/14] fixes --- MetadataProvider/AssemblyExtractor.cs | 165 ++++++++++------------ MetadataProvider/SignatureTypeProvider.cs | 15 +- Model/Assembly.cs | 4 +- Model/Bytecode/Instructions.cs | 6 + Model/ThreeAddressCode/Operands.cs | 3 + Model/Types/TypeDefinitions.cs | 69 ++++++++- Model/Types/Types.cs | 72 ++++++++++ 7 files changed, 235 insertions(+), 99 deletions(-) diff --git a/MetadataProvider/AssemblyExtractor.cs b/MetadataProvider/AssemblyExtractor.cs index 66787d90..feaa58fd 100644 --- a/MetadataProvider/AssemblyExtractor.cs +++ b/MetadataProvider/AssemblyExtractor.cs @@ -13,75 +13,6 @@ namespace MetadataProvider { internal class AssemblyExtractor { - #region FakeArrayType - - private struct FakeArrayType : IBasicType - { - public ArrayType Type { get; private set; } - - public FakeArrayType(ArrayType type) - { - this.Type = type; - } - - public IAssemblyReference ContainingAssembly - { - get { return null; } - } - - public string ContainingNamespace - { - get { return string.Empty; } - } - - public string Name - { - get { return "FakeArray"; } - } - - public string GenericName - { - get { return this.Name; } - } - - public IList GenericArguments - { - get { return null; } - } - - public IBasicType GenericType - { - get { return null; } - } - - public TypeDefinition ResolvedType - { - get { return null; } - } - - public TypeKind TypeKind - { - get { return TypeKind.ReferenceType; } - } - - public ISet Attributes - { - get { return null; } - } - - public int GenericParameterCount - { - get { return 0; } - } - - public IBasicType ContainingType - { - get { return null; } - } - } - - #endregion - private IDictionary definedTypes; private IDictionary definedMethods; private IDictionary definedFields; @@ -127,9 +58,14 @@ public TypeDefinition GetDefinedType(SRM.TypeDefinitionHandle handle) { var typedef = metadata.GetTypeDefinition(handle); var name = metadata.GetString(typedef.Name); - name = GetGenericName(name); + name = GetGenericName(name, out var genericParameterCount); - result = new TypeDefinition(name); + result = new TypeDefinition(name) + { + GenericParameterCount = genericParameterCount, + ContainingAssembly = assembly, + ContainingNamespace = currentNamespace + }; definedTypes.Add(handle, result); } @@ -145,9 +81,13 @@ public MethodDefinition GetDefinedMethod(SRM.MethodDefinitionHandle handle) { var methoddef = metadata.GetMethodDefinition(handle); var name = metadata.GetString(methoddef.Name); - name = GetGenericName(name); + name = GetGenericName(name, out _); result = new MethodDefinition(name, null); + foreach (var genericParameterHandle in methoddef.GetGenericParameters()) + { + ExtractGenericParameter(GenericParameterKind.Method, result, genericParameterHandle); + } definedMethods.Add(handle, result); } @@ -175,13 +115,19 @@ public Assembly Extract() { var assemblydef = metadata.GetAssemblyDefinition(); var name = metadata.GetString(assemblydef.Name); - assembly = new Assembly(name); + assembly = new Assembly(name) + { + Version = assemblydef.Version + }; foreach (var handle in metadata.AssemblyReferences) { var referencedef = metadata.GetAssemblyReference(handle); name = metadata.GetString(referencedef.Name); - var reference = new AssemblyReference(name); + var reference = new AssemblyReference(name) + { + Version = referencedef.Version + }; assembly.References.Add(reference); } @@ -281,6 +227,11 @@ private void ExtractType(SRM.TypeDefinitionHandle typedefHandle) } defGenericContext.TypeParameters.Clear(); + + foreach (var handle in typedef.GetProperties()) + { + ExtractProperty(handle); + } foreach (var handle in typedef.GetNestedTypes()) { @@ -495,6 +446,25 @@ private Constant ExtractFieldDefaultValue(SRM.FieldDefinition fielddef) return result; } + + private void ExtractProperty(SRM.PropertyDefinitionHandle handle) + { + var propertyDef = metadata.GetPropertyDefinition(handle); + var name = metadata.GetString(propertyDef.Name); + CreateGenericParameterReferences(GenericParameterKind.Type, currentType.GenericParameters.Count); + var signature = propertyDef.DecodeSignature(signatureTypeProvider, refGenericContext); + var getter = propertyDef.GetAccessors().Getter; + var setter = propertyDef.GetAccessors().Setter; + var property = new PropertyDefinition(name, signature.ReturnType) + { + Getter = !getter.IsNil ? GetDefinedMethod(getter) : default, + Setter = !setter.IsNil ? GetDefinedMethod(setter) : default, + ContainingType = currentType, + IsInstanceProperty = signature.Header.IsInstance + }; + currentType.PropertyDefinitions.Add(property); + BindGenericParameterReferences(GenericParameterKind.Type, currentType); + } private void ExtractMethod(SRM.MethodDefinitionHandle methoddefHandle) { @@ -632,7 +602,11 @@ private void ExtractParameters(IList parameters) type = signatureTypeProvider.GetByReferenceType(type); } - var v = new LocalVariable("this", true) { Type = type }; + var v = new LocalVariable("this", true) + { + Type = type, + Index = parameters.Count + }; parameters.Add(v); } @@ -640,7 +614,8 @@ private void ExtractParameters(IList parameters) { var v = new LocalVariable(parameter.Name, true) { - Type = parameter.Type + Type = parameter.Type, + Index = parameters.Count }; parameters.Add(v); @@ -659,7 +634,8 @@ private void ExtractLocalVariables(SRM.MethodBodyBlock bodyBlock, IList(op); IInstruction instruction; - if (method.ContainingType is FakeArrayType) + if (method.ContainingType is ArrayTypeWrapper) { - var arrayType = (FakeArrayType)method.ContainingType; + var arrayType = (ArrayTypeWrapper)method.ContainingType; var withLowerBounds = method.Parameters.Count > arrayType.Type.Rank; - - instruction = ProcessCreateArray(op, arrayType.Type, withLowerBounds); + var createArrayInstruction = ProcessCreateArray(op, arrayType.Type, withLowerBounds); + createArrayInstruction.Constructor = method; + instruction = createArrayInstruction; } else { @@ -1450,19 +1427,22 @@ private IInstruction ProcessMethodCall(ILInstruction op) var method = GetOperand(op); IInstruction instruction; - if (method.ContainingType is FakeArrayType) + if (method.ContainingType is ArrayTypeWrapper) { - var arrayType = (FakeArrayType)method.ContainingType; + var arrayType = (ArrayTypeWrapper)method.ContainingType; if (method.Name == "Set") { - instruction = ProcessStoreArrayElement(op, arrayType.Type); + var storeArrayElementInstruction = ProcessStoreArrayElement(op, arrayType.Type); + storeArrayElementInstruction.Method = method; + instruction = storeArrayElementInstruction; } else { var operation = OperationHelper.ToLoadArrayElementOperation(method.Name); - - instruction = ProcessLoadArrayElement(op, arrayType.Type, operation); + var loadArrayElementInstruction = ProcessLoadArrayElement(op, operation, arrayType.Type); + loadArrayElementInstruction.Method = method; + instruction = loadArrayElementInstruction; } } else @@ -1652,12 +1632,15 @@ private IInstruction ProcessConversion(ILInstruction op) #endregion - private static string GetGenericName(string name) + private static string GetGenericName(string name, out int genericParameterCount) { var start = name.LastIndexOf('`'); + genericParameterCount = 0; if (start > -1) { + var count = name.Substring(start + 1); + genericParameterCount = Convert.ToInt32(count); name = name.Remove(start); } diff --git a/MetadataProvider/SignatureTypeProvider.cs b/MetadataProvider/SignatureTypeProvider.cs index 9ce7a48e..e6e921db 100644 --- a/MetadataProvider/SignatureTypeProvider.cs +++ b/MetadataProvider/SignatureTypeProvider.cs @@ -75,7 +75,10 @@ public virtual IType GetTypeFromReference(SRM.MetadataReader reader, SRM.TypeRef var assemblyHandle = (SRM.AssemblyReferenceHandle)typeref.ResolutionScope; var assembly = reader.GetAssemblyReference(assemblyHandle); name = reader.GetString(assembly.Name); - type.ContainingAssembly = new AssemblyReference(name); + type.ContainingAssembly = new AssemblyReference(name) + { + Version = assembly.Version + }; break; } @@ -171,6 +174,16 @@ public virtual IType GetPinnedType(IType targetType) public virtual IType GetGenericInstantiation(IType genericType, ImmutableArray genericArguments) { var result = genericType as IBasicType; + switch (result) + { + case BasicType basicType: + basicType.GenericParameterCount = genericArguments.Length; + break; + case TypeDefinition typeDefinition: + typeDefinition.GenericParameterCount = genericArguments.Length; + break; + } + result = result.Instantiate(genericArguments); return result; } diff --git a/Model/Assembly.cs b/Model/Assembly.cs index 454bae9e..2d2994a3 100644 --- a/Model/Assembly.cs +++ b/Model/Assembly.cs @@ -12,11 +12,13 @@ namespace Model public interface IAssemblyReference { string Name { get; } + Version Version { get; } } public class AssemblyReference : IAssemblyReference { public string Name { get; private set; } + public Version Version { get; set; } public AssemblyReference(string name) { @@ -49,7 +51,7 @@ public class Assembly : IAssemblyReference public string Name { get; private set; } public IList References { get; private set; } public Namespace RootNamespace { get; set; } - + public Version Version { get; set; } public Assembly(string name) { this.Name = name; diff --git a/Model/Bytecode/Instructions.cs b/Model/Bytecode/Instructions.cs index bb12534e..8cf7d27a 100644 --- a/Model/Bytecode/Instructions.cs +++ b/Model/Bytecode/Instructions.cs @@ -245,6 +245,8 @@ public class CreateArrayInstruction : Instruction public ArrayType Type { get; set; } public bool WithLowerBound { get; set; } + public IMethodReference Constructor { get; set; } + public CreateArrayInstruction(uint label, ArrayType type) : base(label) { @@ -266,6 +268,8 @@ public override string ToString() public class LoadArrayElementInstruction : Instruction { public LoadArrayElementOperation Operation { get; set; } + + public IMethodReference Method { get; set; } public ArrayType Array { get; set; } public LoadArrayElementInstruction(uint label, LoadArrayElementOperation operation, ArrayType array) @@ -290,6 +294,8 @@ public override string ToString() public class StoreArrayElementInstruction : Instruction { public ArrayType Array { get; set; } + + public IMethodReference Method { get; set; } public StoreArrayElementInstruction(uint label, ArrayType array) : base(label) diff --git a/Model/ThreeAddressCode/Operands.cs b/Model/ThreeAddressCode/Operands.cs index 7d658fe9..39ab1072 100644 --- a/Model/ThreeAddressCode/Operands.cs +++ b/Model/ThreeAddressCode/Operands.cs @@ -292,6 +292,9 @@ public class LocalVariable : IVariable public string Name { get; set; } public IType Type { get; set; } public bool IsParameter { get; set; } + + // int? because int defaults to 0 if not present + public int? Index { get; set; } public LocalVariable(string name, bool isParameter = false) { diff --git a/Model/Types/TypeDefinitions.cs b/Model/Types/TypeDefinitions.cs index 27062ea7..7f4b1475 100644 --- a/Model/Types/TypeDefinitions.cs +++ b/Model/Types/TypeDefinitions.cs @@ -397,7 +397,66 @@ public override bool Equals(object obj) return result; } } + public class PropertyDefinition : ITypeMemberDefinition + { + public PropertyDefinition(string name, IType propType) + { + PropertyType = propType; + Name = name; + Attributes = new HashSet(); + } + + public ISet Attributes { get; private set; } + public IType PropertyType { get; set; } + public string Name { get; set; } + public MethodDefinition Getter { get; set; } + public MethodDefinition Setter { get; set; } + public TypeDefinition ContainingType { get; set; } + IBasicType ITypeMemberReference.ContainingType + { + get { return this.ContainingType; } + } + public bool IsInstanceProperty { get; set; } + public bool MatchReference(ITypeMemberReference member) + { + if (member is PropertyDefinition) + return member.Equals(this); + return false; + } + public override bool Equals(object obj) + { + if (obj is PropertyDefinition propertyDef) + { + bool hasSetter = (propertyDef.Setter != null) == (this.Setter != null); + bool hasGetter = (propertyDef.Getter != null) == (this.Getter != null); + return propertyDef.Name.Equals(this.Name) && + propertyDef.PropertyType.Equals(this.PropertyType) && + hasSetter && hasGetter && + (propertyDef.Getter == null || propertyDef.Getter.Equals(this.Getter)) && + (propertyDef.Setter == null || propertyDef.Setter.Equals(this.Setter)) && + (propertyDef.ContainingType.Equals(this.ContainingType)); + } + return false; + } + public override string ToString() + { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.AppendLine("Property definition"); + stringBuilder.AppendLine(String.Format("Name: {0}", Name)); + stringBuilder.AppendLine(String.Format("Property type: {0}", PropertyType)); + stringBuilder.AppendLine(String.Format("Containing type: {0}", ContainingType)); + if (Getter != null) + stringBuilder.AppendLine(String.Format("Getter: {0}", Getter.ToSignatureString())); + if (Setter != null) + stringBuilder.AppendLine(String.Format("Setter: {0}", Setter.ToSignatureString())); + return stringBuilder.ToString(); + } + public override int GetHashCode() + { + return this.Name.GetHashCode(); + } + } public class MethodDefinition : ITypeMemberDefinition, IMethodReference, IGenericDefinition { public VisibilityKind Visibility { get; set; } @@ -623,7 +682,9 @@ public class TypeDefinition : IBasicType, IGenericDefinition, ITypeMemberDefinit public IList Methods { get; private set; } public IList Types { get; private set; } public IBasicType UnderlayingType { get; set; } - + public ISet PropertyDefinitions { get; private set; } + + public int GenericParameterCount { get; set; } public TypeDefinition(string name, TypeKind typeKind = TypeKind.Unknown, TypeDefinitionKind kind = TypeDefinitionKind.Unknown) { this.Name = name; @@ -635,6 +696,7 @@ public TypeDefinition(string name, TypeKind typeKind = TypeKind.Unknown, TypeDef this.Fields = new List(); this.Methods = new List(); this.Types = new List(); + this.PropertyDefinitions = new HashSet(); } public string GenericName @@ -676,11 +738,6 @@ IBasicType ITypeMemberReference.ContainingType #region IGenericReference members - int IGenericReference.GenericParameterCount - { - get { return this.GenericParameters.Count; } - } - #endregion #region IBasicType members diff --git a/Model/Types/Types.cs b/Model/Types/Types.cs index 0d6934db..e26edc8b 100644 --- a/Model/Types/Types.cs +++ b/Model/Types/Types.cs @@ -37,6 +37,9 @@ public interface IReferenceType : IType public static class PlatformTypes { + public static Boolean Includes(IType type) => platformTypes.FirstOrDefault(type.Equals) != null; + + private static readonly ICollection platformTypes = new List(); public static readonly UnknownType Unknown = UnknownType.Value; @@ -732,4 +735,73 @@ public override bool Equals(object obj) return result; } } + + #region ArrayTypeWrapper + + public struct ArrayTypeWrapper : IBasicType + { + public ArrayType Type { get; } + + public ArrayTypeWrapper(ArrayType type) + { + this.Type = type; + } + + public IAssemblyReference ContainingAssembly + { + get { return null; } + } + + public string ContainingNamespace + { + get { return string.Empty; } + } + + public string Name + { + get { return "ArrayTypeWrapper"; } + } + + public string GenericName + { + get { return this.Name; } + } + + public IList GenericArguments + { + get { return null; } + } + + public IBasicType GenericType + { + get { return null; } + } + + public TypeDefinition ResolvedType + { + get { return null; } + } + + public TypeKind TypeKind + { + get { return TypeKind.ReferenceType; } + } + + public ISet Attributes + { + get { return null; } + } + + public int GenericParameterCount + { + get { return 0; } + } + + public IBasicType ContainingType + { + get { return null; } + } + } + + #endregion } From d633147ed1b8e6f8f074b710afbdbdda25bf6887 Mon Sep 17 00:00:00 2001 From: fcurdi Date: Fri, 10 Apr 2020 10:50:02 -0300 Subject: [PATCH 03/14] more fixes --- MetadataProvider/AssemblyExtractor.cs | 92 +++++++++++++---------- MetadataProvider/SignatureTypeProvider.cs | 10 --- Model/Types/TypeDefinitions.cs | 7 +- 3 files changed, 58 insertions(+), 51 deletions(-) diff --git a/MetadataProvider/AssemblyExtractor.cs b/MetadataProvider/AssemblyExtractor.cs index feaa58fd..ff6f7e46 100644 --- a/MetadataProvider/AssemblyExtractor.cs +++ b/MetadataProvider/AssemblyExtractor.cs @@ -58,14 +58,19 @@ public TypeDefinition GetDefinedType(SRM.TypeDefinitionHandle handle) { var typedef = metadata.GetTypeDefinition(handle); var name = metadata.GetString(typedef.Name); - name = GetGenericName(name, out var genericParameterCount); + name = GetGenericName(name); result = new TypeDefinition(name) { - GenericParameterCount = genericParameterCount, ContainingAssembly = assembly, ContainingNamespace = currentNamespace }; + + foreach (var genericParameterHandle in typedef.GetGenericParameters()) + { + ExtractGenericParameter(GenericParameterKind.Type, result, genericParameterHandle); + } + definedTypes.Add(handle, result); } @@ -81,13 +86,14 @@ public MethodDefinition GetDefinedMethod(SRM.MethodDefinitionHandle handle) { var methoddef = metadata.GetMethodDefinition(handle); var name = metadata.GetString(methoddef.Name); - name = GetGenericName(name, out _); + name = GetGenericName(name); result = new MethodDefinition(name, null); foreach (var genericParameterHandle in methoddef.GetGenericParameters()) { ExtractGenericParameter(GenericParameterKind.Method, result, genericParameterHandle); } + definedMethods.Add(handle, result); } @@ -190,13 +196,11 @@ private void ExtractType(SRM.TypeDefinitionHandle typedefHandle) } type.ContainingType = currentType; - type.ContainingAssembly = assembly; - type.ContainingNamespace = currentNamespace; currentType = type; - foreach (var handle in typedef.GetGenericParameters()) + foreach (var genericParameter in type.GenericParameters) { - ExtractGenericParameter(GenericParameterKind.Type, type, handle); + defGenericContext.TypeParameters.Add(genericParameter); } ExtractBaseType(typedef.BaseType); @@ -396,19 +400,6 @@ private void ExtractGenericParameter(GenericParameterKind parameterKind, IGeneri GenericContainer = genericContainer }; - if (parameterKind == GenericParameterKind.Type) - { - defGenericContext.TypeParameters.Add(genericParameter); - } - else if (parameterKind == GenericParameterKind.Method) - { - defGenericContext.MethodParameters.Add(genericParameter); - } - else - { - throw parameterKind.ToUnknownValueException(); - } - genericContainer.GenericParameters.Add(genericParameter); } @@ -460,7 +451,7 @@ private void ExtractProperty(SRM.PropertyDefinitionHandle handle) Getter = !getter.IsNil ? GetDefinedMethod(getter) : default, Setter = !setter.IsNil ? GetDefinedMethod(setter) : default, ContainingType = currentType, - IsInstanceProperty = signature.Header.IsInstance + IsStatic = !signature.Header.IsInstance }; currentType.PropertyDefinitions.Add(property); BindGenericParameterReferences(GenericParameterKind.Type, currentType); @@ -482,9 +473,9 @@ private void ExtractMethod(SRM.MethodDefinitionHandle methoddefHandle) currentType.Methods.Add(method); currentMethod = method; - foreach (var handle in methoddef.GetGenericParameters()) + foreach (var genericParameter in method.GenericParameters) { - ExtractGenericParameter(GenericParameterKind.Method, method, handle); + defGenericContext.MethodParameters.Add(genericParameter); } var signature = methoddef.DecodeSignature(signatureTypeProvider, defGenericContext); @@ -940,10 +931,16 @@ private IInstruction ExtractInstruction(ILInstruction operation) break; case SRM.ILOpCode.Ldfld: + instruction = ProcessLoadField(operation, false); + break; case SRM.ILOpCode.Ldsfld: + instruction = ProcessLoadField(operation, true); + break; case SRM.ILOpCode.Ldflda: + instruction = ProcessLoadField(operation, false); + break; case SRM.ILOpCode.Ldsflda: - instruction = ProcessLoadField(operation); + instruction = ProcessLoadField(operation, true); break; case SRM.ILOpCode.Ldftn: @@ -1058,8 +1055,10 @@ private IInstruction ExtractInstruction(ILInstruction operation) break; case SRM.ILOpCode.Stfld: + instruction = ProcessStoreField(operation, false); + break; case SRM.ILOpCode.Stsfld: - instruction = ProcessStoreField(operation); + instruction = ProcessStoreField(operation, true); break; case SRM.ILOpCode.Stind_i: @@ -1544,11 +1543,12 @@ private IInstruction ProcessLoadIndirect(ILInstruction op) return instruction; } - private IInstruction ProcessLoadField(ILInstruction op) + private IInstruction ProcessLoadField(ILInstruction op, bool isStatic) { var operation = OperationHelper.ToLoadFieldOperation(op.Opcode); var field = GetOperand(op); + SetFieldStaticProperty(field, isStatic); var instruction = new LoadFieldInstruction(op.Offset, operation, field); return instruction; } @@ -1588,10 +1588,11 @@ private IInstruction ProcessStoreLocal(ILInstruction op) return instruction; } - private IInstruction ProcessStoreField(ILInstruction op) + private IInstruction ProcessStoreField(ILInstruction op, bool isStatic) { var field = GetOperand(op); - + + SetFieldStaticProperty(field, isStatic); var instruction = new StoreFieldInstruction(op.Offset, field); return instruction; } @@ -1615,11 +1616,7 @@ private IInstruction ProcessConversion(ILInstruction op) var unsigned = OperationHelper.OperandsAreUnsigned(op.Opcode); var type = GetOperand(op); - if (operation == ConvertOperation.Box && type.TypeKind == TypeKind.ValueType) - { - type = PlatformTypes.Object; - } - else if (operation == ConvertOperation.Conv) + if (operation == ConvertOperation.Conv) { type = OperationHelper.GetOperationType(op.Opcode); } @@ -1632,19 +1629,38 @@ private IInstruction ProcessConversion(ILInstruction op) #endregion - private static string GetGenericName(string name, out int genericParameterCount) + private static string GetGenericName(string name) { var start = name.LastIndexOf('`'); - genericParameterCount = 0; - + if (start > -1) { - var count = name.Substring(start + 1); - genericParameterCount = Convert.ToInt32(count); name = name.Remove(start); } return name; } + + // FIXME + // Metadata static indicator for FieldReferences (!signatureHeader.IsInstance) appears to be incorrect when read. Maybe it is updated when + // it can resolve the reference. So field isStatic is ensured with the field operation kind (ex: stsfld => static, ldfld => not static) + private static void SetFieldStaticProperty(IFieldReference field, bool isStatic) + { + switch (field) + { + case FieldReference fieldReference: + { + fieldReference.IsStatic = isStatic; + break; + } + case FieldDefinition fieldDefinition: + { + fieldDefinition.IsStatic = isStatic; + break; + } + default: throw new Exception("case not handled"); + + } + } } } \ No newline at end of file diff --git a/MetadataProvider/SignatureTypeProvider.cs b/MetadataProvider/SignatureTypeProvider.cs index e6e921db..a17fdc13 100644 --- a/MetadataProvider/SignatureTypeProvider.cs +++ b/MetadataProvider/SignatureTypeProvider.cs @@ -174,16 +174,6 @@ public virtual IType GetPinnedType(IType targetType) public virtual IType GetGenericInstantiation(IType genericType, ImmutableArray genericArguments) { var result = genericType as IBasicType; - switch (result) - { - case BasicType basicType: - basicType.GenericParameterCount = genericArguments.Length; - break; - case TypeDefinition typeDefinition: - typeDefinition.GenericParameterCount = genericArguments.Length; - break; - } - result = result.Instantiate(genericArguments); return result; } diff --git a/Model/Types/TypeDefinitions.cs b/Model/Types/TypeDefinitions.cs index 7f4b1475..4271ec11 100644 --- a/Model/Types/TypeDefinitions.cs +++ b/Model/Types/TypeDefinitions.cs @@ -397,7 +397,7 @@ public override bool Equals(object obj) return result; } } - public class PropertyDefinition : ITypeMemberDefinition + public class PropertyDefinition : ITypeMemberDefinition, IMetadataReference { public PropertyDefinition(string name, IType propType) { @@ -416,7 +416,7 @@ IBasicType ITypeMemberReference.ContainingType { get { return this.ContainingType; } } - public bool IsInstanceProperty { get; set; } + public bool IsStatic { get; set; } public bool MatchReference(ITypeMemberReference member) { if (member is PropertyDefinition) @@ -684,7 +684,8 @@ public class TypeDefinition : IBasicType, IGenericDefinition, ITypeMemberDefinit public IBasicType UnderlayingType { get; set; } public ISet PropertyDefinitions { get; private set; } - public int GenericParameterCount { get; set; } + public int GenericParameterCount => GenericParameters.Count; + public TypeDefinition(string name, TypeKind typeKind = TypeKind.Unknown, TypeDefinitionKind kind = TypeDefinitionKind.Unknown) { this.Name = name; From 14b1be0ea1a9fc35fc98b4f545caa45b27409431 Mon Sep 17 00:00:00 2001 From: fcurdi Date: Fri, 10 Apr 2020 13:44:28 -0300 Subject: [PATCH 04/14] fix namespace in GetDefinedType --- MetadataProvider/AssemblyExtractor.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MetadataProvider/AssemblyExtractor.cs b/MetadataProvider/AssemblyExtractor.cs index ff6f7e46..8253533a 100644 --- a/MetadataProvider/AssemblyExtractor.cs +++ b/MetadataProvider/AssemblyExtractor.cs @@ -63,7 +63,7 @@ public TypeDefinition GetDefinedType(SRM.TypeDefinitionHandle handle) result = new TypeDefinition(name) { ContainingAssembly = assembly, - ContainingNamespace = currentNamespace + ContainingNamespace = new Namespace(metadata.GetString(typedef.Namespace)) }; foreach (var genericParameterHandle in typedef.GetGenericParameters()) @@ -196,6 +196,8 @@ private void ExtractType(SRM.TypeDefinitionHandle typedefHandle) } type.ContainingType = currentType; + type.ContainingAssembly = assembly; + type.ContainingNamespace = currentNamespace; currentType = type; foreach (var genericParameter in type.GenericParameters) From affb9d5bcbd0449f1d16ffdd7067877c76623487 Mon Sep 17 00:00:00 2001 From: fcurdi Date: Tue, 14 Apr 2020 19:21:12 -0300 Subject: [PATCH 05/14] add culture and public key --- MetadataProvider/AssemblyExtractor.cs | 8 ++++++-- Model/Assembly.cs | 6 ++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/MetadataProvider/AssemblyExtractor.cs b/MetadataProvider/AssemblyExtractor.cs index 8253533a..092df7f2 100644 --- a/MetadataProvider/AssemblyExtractor.cs +++ b/MetadataProvider/AssemblyExtractor.cs @@ -123,7 +123,9 @@ public Assembly Extract() var name = metadata.GetString(assemblydef.Name); assembly = new Assembly(name) { - Version = assemblydef.Version + Version = assemblydef.Version, + Culture = metadata.GetString(assemblydef.Culture), + PublicKey = metadata.GetBlobBytes(assemblydef.PublicKey) }; foreach (var handle in metadata.AssemblyReferences) @@ -132,7 +134,9 @@ public Assembly Extract() name = metadata.GetString(referencedef.Name); var reference = new AssemblyReference(name) { - Version = referencedef.Version + Version = referencedef.Version, + Culture = metadata.GetString(referencedef.Culture), + PublicKey = metadata.GetBlobBytes(referencedef.PublicKeyOrToken) }; assembly.References.Add(reference); diff --git a/Model/Assembly.cs b/Model/Assembly.cs index 2d2994a3..c3fc6b29 100644 --- a/Model/Assembly.cs +++ b/Model/Assembly.cs @@ -13,12 +13,16 @@ public interface IAssemblyReference { string Name { get; } Version Version { get; } + string Culture { get; } + byte[] PublicKey { get; } } public class AssemblyReference : IAssemblyReference { public string Name { get; private set; } public Version Version { get; set; } + public string Culture { get; set; } + public byte[] PublicKey { get; set; } public AssemblyReference(string name) { @@ -52,6 +56,8 @@ public class Assembly : IAssemblyReference public IList References { get; private set; } public Namespace RootNamespace { get; set; } public Version Version { get; set; } + public string Culture { get; set; } + public byte[] PublicKey { get; set; } public Assembly(string name) { this.Name = name; From 143630d633f913ec97e4c9c1af8129c8a4df193a Mon Sep 17 00:00:00 2001 From: fcurdi Date: Wed, 15 Apr 2020 23:25:08 -0300 Subject: [PATCH 06/14] generic parameter constraints --- CCIProvider/TypeExtractor.cs | 26 +++++++++++++++++++++++++- MetadataProvider/AssemblyExtractor.cs | 15 ++++++++++++++- Model/Types/Types.cs | 9 +++++++++ 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/CCIProvider/TypeExtractor.cs b/CCIProvider/TypeExtractor.cs index 39e813c8..b00bf07b 100644 --- a/CCIProvider/TypeExtractor.cs +++ b/CCIProvider/TypeExtractor.cs @@ -7,7 +7,16 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using Microsoft.Cci.MutableCodeModel; +using AssemblyReference = Model.AssemblyReference; using Cci = Microsoft.Cci; +using CustomAttribute = Model.Types.CustomAttribute; +using FieldDefinition = Model.Types.FieldDefinition; +using FieldReference = Model.Types.FieldReference; +using GenericParameter = Model.Types.GenericParameter; +using MethodBody = Model.Types.MethodBody; +using MethodDefinition = Model.Types.MethodDefinition; +using MethodReference = Model.Types.MethodReference; namespace CCIProvider { @@ -810,7 +819,22 @@ private void ExtractGenericTypeParameters(IGenericDefinition definingType, Cci.I var index = (ushort)i; var name = parameterdef.Name.Value; var typeKind = GetGenericParameterTypeKind(parameterdef); - var parameter = new GenericParameter(GenericParameterKind.Type, index, name, typeKind); + var variance = GenericParameterVariance.NONE; + switch (parameterdef.Variance) + { + case Cci.TypeParameterVariance.Contravariant: + variance = GenericParameterVariance.CONTRAVARIANT; + break; + case Cci.TypeParameterVariance.Covariant: + variance = GenericParameterVariance.COVARIANT; + break; + } + + var parameter = new GenericParameter(GenericParameterKind.Type, index, name, typeKind) + { + Variance = variance, + DefaultConstructorConstraint = parameterdef.MustHaveDefaultConstructor + }; ExtractAttributes(parameter.Attributes, parameterdef.Attributes); diff --git a/MetadataProvider/AssemblyExtractor.cs b/MetadataProvider/AssemblyExtractor.cs index 91923e0e..e08294a5 100644 --- a/MetadataProvider/AssemblyExtractor.cs +++ b/MetadataProvider/AssemblyExtractor.cs @@ -400,10 +400,23 @@ private void ExtractGenericParameter(GenericParameterKind parameterKind, IGeneri typeKind = TypeKind.ValueType; } + var variance = GenericParameterVariance.NONE; + if (genericParameterdef.Attributes.HasFlag(SR.GenericParameterAttributes.Contravariant)) + { + variance = GenericParameterVariance.CONTRAVARIANT; + } + + if (genericParameterdef.Attributes.HasFlag(SR.GenericParameterAttributes.Covariant)) + { + variance = GenericParameterVariance.COVARIANT; + } + var name = metadata.GetString(genericParameterdef.Name); var genericParameter = new GenericParameter(parameterKind, (ushort)genericParameterdef.Index, name, typeKind) { - GenericContainer = genericContainer + GenericContainer = genericContainer, + Variance = variance, + DefaultConstructorConstraint = genericParameterdef.Attributes.HasFlag(SR.GenericParameterAttributes.DefaultConstructorConstraint) }; genericContainer.GenericParameters.Add(genericParameter); diff --git a/Model/Types/Types.cs b/Model/Types/Types.cs index a15346f2..a1c73ecd 100644 --- a/Model/Types/Types.cs +++ b/Model/Types/Types.cs @@ -538,11 +538,20 @@ private static string GetName(GenericParameterKind kind, ushort index) return string.Format("{0}{1}", prefix, index); } } + + public enum GenericParameterVariance + { + COVARIANT, + CONTRAVARIANT, + NONE + } public class GenericParameter : IGenericParameterReference { public ISet Attributes { get; private set; } public ISet Constraints { get; private set; } + public bool DefaultConstructorConstraint { get; set; } + public GenericParameterVariance Variance { get; set; } public TypeKind TypeKind { get; set; } public IGenericDefinition GenericContainer { get; set; } public GenericParameterKind Kind { get; set; } From 905a56619eaf2a5a5659d140f81319905046238a Mon Sep 17 00:00:00 2001 From: fcurdi Date: Wed, 15 Apr 2020 23:33:41 -0300 Subject: [PATCH 07/14] fix --- CCIProvider/TypeExtractor.cs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/CCIProvider/TypeExtractor.cs b/CCIProvider/TypeExtractor.cs index b00bf07b..b0b31929 100644 --- a/CCIProvider/TypeExtractor.cs +++ b/CCIProvider/TypeExtractor.cs @@ -7,16 +7,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using Microsoft.Cci.MutableCodeModel; -using AssemblyReference = Model.AssemblyReference; using Cci = Microsoft.Cci; -using CustomAttribute = Model.Types.CustomAttribute; -using FieldDefinition = Model.Types.FieldDefinition; -using FieldReference = Model.Types.FieldReference; -using GenericParameter = Model.Types.GenericParameter; -using MethodBody = Model.Types.MethodBody; -using MethodDefinition = Model.Types.MethodDefinition; -using MethodReference = Model.Types.MethodReference; namespace CCIProvider { From fa78c9533f31e67dd48392c8231137ef1f211e4c Mon Sep 17 00:00:00 2001 From: fcurdi Date: Wed, 15 Apr 2020 23:37:24 -0300 Subject: [PATCH 08/14] remove unused method --- Model/Types/Types.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/Model/Types/Types.cs b/Model/Types/Types.cs index a1c73ecd..88e701e1 100644 --- a/Model/Types/Types.cs +++ b/Model/Types/Types.cs @@ -37,9 +37,6 @@ public interface IReferenceType : IType public static class PlatformTypes { - public static Boolean Includes(IType type) => platformTypes.FirstOrDefault(type.Equals) != null; - - private static readonly ICollection platformTypes = new List(); public static readonly UnknownType Unknown = UnknownType.Value; From 57598d86834c955510b2cbd07215c2fadf238f17 Mon Sep 17 00:00:00 2001 From: fcurdi Date: Fri, 1 May 2020 16:48:01 -0300 Subject: [PATCH 09/14] method overrides, generic constraints --- MetadataProvider/AssemblyExtractor.cs | 107 ++++++++++++++++++++++---- Model/Extensions.cs | 49 +++++++++++- Model/Types/TypeDefinitions.cs | 50 +----------- Model/Types/Types.cs | 17 +++- 4 files changed, 160 insertions(+), 63 deletions(-) diff --git a/MetadataProvider/AssemblyExtractor.cs b/MetadataProvider/AssemblyExtractor.cs index e08294a5..140f1d74 100644 --- a/MetadataProvider/AssemblyExtractor.cs +++ b/MetadataProvider/AssemblyExtractor.cs @@ -231,9 +231,10 @@ private void ExtractType(SRM.TypeDefinitionHandle typedefHandle) type.UnderlayingType = valueField.Type as IBasicType; } + var methodOverrides = MethodOverridesOf(typedef); foreach (var handle in typedef.GetMethods()) { - ExtractMethod(handle); + ExtractMethod(handle, methodOverrides); } defGenericContext.TypeParameters.Clear(); @@ -420,10 +421,18 @@ private void ExtractGenericParameter(GenericParameterKind parameterKind, IGeneri }; genericContainer.GenericParameters.Add(genericParameter); - var constraints = genericParameterdef.GetConstraints().Select( - constraint => signatureTypeProvider.GetTypeFromHandle(metadata, defGenericContext, metadata.GetGenericParameterConstraint(constraint).Type - )); - genericParameter.Constraints.AddRange(constraints); + var typeConstraints = genericParameterdef.GetConstraints().Select( + constraint => + { + refGenericContext.MethodParameters.Clear(); + refGenericContext.TypeParameters.Clear(); + CreateGenericParameterReferences(parameterKind, genericContainer.GenericParameterCount); + var constraints = signatureTypeProvider.GetTypeFromHandle(metadata, refGenericContext, + metadata.GetGenericParameterConstraint(constraint).Type); + BindGenericParameterReferences(parameterKind, genericContainer); + return constraints; + }); + genericParameter.Constraints.AddRange(typeConstraints); } private void ExtractField(SRM.FieldDefinitionHandle handle) @@ -480,7 +489,7 @@ private void ExtractProperty(SRM.PropertyDefinitionHandle handle) BindGenericParameterReferences(GenericParameterKind.Type, currentType); } - private void ExtractMethod(SRM.MethodDefinitionHandle methoddefHandle) + private void ExtractMethod(SRM.MethodDefinitionHandle methoddefHandle, IList methodOverrides) { var methoddef = metadata.GetMethodDefinition(methoddefHandle); var method = GetDefinedMethod(methoddefHandle); @@ -511,6 +520,12 @@ private void ExtractMethod(SRM.MethodDefinitionHandle methoddefHandle) ExtractLocalVariablesNames(methoddefHandle); ExtractMethodBody(methoddef.RelativeVirtualAddress); + + var methodOverride = methodOverrides.FirstOrDefault(m => method.MatchSignature(m.newMethodImplementation)); + if (methodOverride != null) + { + method.OverridenMethod = methodOverride.overridenMethod; + } defGenericContext.MethodParameters.Clear(); currentMethod = null; @@ -1258,11 +1273,20 @@ private IFieldReference GetFieldReference(SRM.MemberReference member) BindGenericParameterReferences(GenericParameterKind.Type, containingType); return field; } + + private IMethodReference GetMethodReference(SRM.MemberReference member) => + GetMethodReference(member.Name, member.Parent, member.DecodeMethodSignature); + + private IMethodReference GetMethodReference(SRM.MethodDefinition methodDefinition) => + GetMethodReference(methodDefinition.Name, methodDefinition.GetDeclaringType(), methodDefinition.DecodeSignature); - private IMethodReference GetMethodReference(SRM.MemberReference member) + private IMethodReference GetMethodReference( + SRM.StringHandle methodName, + SRM.EntityHandle parent, + Func> decodeSignature) { - var name = metadata.GetString(member.Name); - var type = signatureTypeProvider.GetTypeFromHandle(metadata, defGenericContext, member.Parent); + var name = metadata.GetString(methodName); + var type = signatureTypeProvider.GetTypeFromHandle(metadata, defGenericContext, parent); if (type is ArrayType) { @@ -1272,7 +1296,7 @@ private IMethodReference GetMethodReference(SRM.MemberReference member) var containingType = (IBasicType)type; CreateGenericParameterReferences(GenericParameterKind.Type, containingType.GenericParameterCount); - var signature = member.DecodeMethodSignature(signatureTypeProvider, refGenericContext); + var signature = decodeSignature(signatureTypeProvider, refGenericContext); var method = new MethodReference(name, signature.ReturnType) { @@ -1664,9 +1688,8 @@ private static string GetGenericName(string name) return name; } - // FIXME - // Metadata static indicator for FieldReferences (!signatureHeader.IsInstance) appears to be incorrect when read. Maybe it is updated when - // it can resolve the reference. So field isStatic is ensured with the field operation kind (ex: stsfld => static, ldfld => not static) + // Metadata static indicator for FieldReferences (!signatureHeader.IsInstance) appears to be incorrect when read. + // So field isStatic is ensured with the field operation kind (ex: stsfld => static, ldfld => not static) private static void SetFieldStaticProperty(IFieldReference field, bool isStatic) { switch (field) @@ -1685,5 +1708,63 @@ private static void SetFieldStaticProperty(IFieldReference field, bool isStatic) } } + + private IList MethodOverridesOf(SRM.TypeDefinition typedef) => + typedef + .GetMethodImplementations() + .Select(handle => metadata.GetMethodImplementation(handle)) + .Select(methodImplementation => + { + IMethodReference newMethodImplementation; + switch (methodImplementation.MethodBody.Kind) + { + case SRM.HandleKind.MethodDefinition: + { + newMethodImplementation = GetMethodReference((SRM.MethodDefinitionHandle) methodImplementation.MethodBody); + break; + } + case SRM.HandleKind.MemberReference: + { + newMethodImplementation = GetMethodReference((SRM.MemberReferenceHandle) methodImplementation.MethodBody); + break; + } + default: + throw new Exception("Unexpected handle kind"); + } + + IMethodReference overridenMethod; + switch (methodImplementation.MethodDeclaration.Kind) + { + case SRM.HandleKind.MethodDefinition: + { + overridenMethod = GetMethodReference( + metadata.GetMethodDefinition((SRM.MethodDefinitionHandle) methodImplementation.MethodDeclaration)); + break; + } + case SRM.HandleKind.MemberReference: + { + overridenMethod = GetMethodReference( + metadata.GetMemberReference((SRM.MemberReferenceHandle) methodImplementation.MethodDeclaration)); + break; + } + default: + throw new Exception("Unexpected handle kind"); + } + + return new MethodOverride(newMethodImplementation, overridenMethod); + }) + .ToList(); + } + + internal class MethodOverride + { + public readonly IMethodReference newMethodImplementation; + public readonly IMethodReference overridenMethod; + + public MethodOverride(IMethodReference newMethodImplementation, IMethodReference overridenMethod) + { + this.newMethodImplementation = newMethodImplementation; + this.overridenMethod = overridenMethod; + } } } \ No newline at end of file diff --git a/Model/Extensions.cs b/Model/Extensions.cs index 8ba54658..ad6be5c7 100644 --- a/Model/Extensions.cs +++ b/Model/Extensions.cs @@ -246,7 +246,7 @@ public static BasicType Instantiate(this IBasicType type, IEnumerable gen ContainingAssembly = type.ContainingAssembly, ContainingNamespace = type.ContainingNamespace, ContainingType = type.ContainingType, - GenericParameterCount = type.GenericParameterCount, + GenericParameterCount = genericArguments.Count(), GenericType = type }; @@ -361,6 +361,53 @@ public static bool IsDelegate(this IType type) return result; } + public static bool MatchSignature(this IMethodReference method, IMethodReference anotherMethod) + { + var result = method.Name == anotherMethod.Name && + method.IsStatic == anotherMethod.IsStatic && + method.GenericParameterCount == anotherMethod.GenericParameterCount && + method.ReturnType.Equals(anotherMethod.ReturnType) && + method.MatchParameters(anotherMethod); + return result; + } + + public static bool MatchParameters(this IMethodReference method, IMethodReference anotherMethod) + { + var result = false; + + if (method.Parameters.Count == anotherMethod.Parameters.Count) + { + result = true; + + for (var i = 0; i < method.Parameters.Count && result; ++i) + { + var parameterdef = method.Parameters[i]; + var parameterref = anotherMethod.Parameters[i]; + + result = parameterdef.MatchReference(parameterref); + } + } + + return result; + } + + public static bool MatchReference(this IMethodParameterReference parameter, IMethodParameterReference anotherParameter) + { + var result = false; + + if (anotherParameter is MethodParameter) + { + result = parameter.Equals(anotherParameter); + } + else + { + result = parameter.Kind == anotherParameter.Kind && + parameter.Type.Equals(anotherParameter.Type); + } + + return result; + } + #region Control-flow helper methods public static bool IsBranch(this IInstruction instruction, out IList targets) diff --git a/Model/Types/TypeDefinitions.cs b/Model/Types/TypeDefinitions.cs index 4271ec11..5678eb23 100644 --- a/Model/Types/TypeDefinitions.cs +++ b/Model/Types/TypeDefinitions.cs @@ -242,23 +242,6 @@ public bool HasDefaultValue get { return this.DefaultValue != null; } } - public bool MatchReference(IMethodParameterReference parameter) - { - var result = false; - - if (parameter is MethodParameter) - { - result = this.Equals(parameter); - } - else - { - result = this.Kind == parameter.Kind && - this.Type.Equals(parameter.Type); - } - - return result; - } - public override string ToString() { string kind; @@ -472,7 +455,8 @@ public class MethodDefinition : ITypeMemberDefinition, IMethodReference, IGeneri public bool IsConstructor { get; set; } public bool IsExternal { get; set; } public MethodBody Body { get; set; } - + public IMethodReference OverridenMethod { get; set; } + public MethodDefinition(string name, IType returnType) { this.Name = name; @@ -569,36 +553,6 @@ public bool MatchReference(ITypeMemberReference member) return result; } - public bool MatchSignature(IMethodReference method) - { - var result = this.Name == method.Name && - this.IsStatic == method.IsStatic && - this.GenericParameters.Count == method.GenericParameterCount && - this.ReturnType.Equals(method.ReturnType) && - this.MatchParameters(method); - return result; - } - - public bool MatchParameters(IMethodReference method) - { - var result = false; - - if (this.Parameters.Count == method.Parameters.Count) - { - result = true; - - for (var i = 0; i < this.Parameters.Count && result; ++i) - { - var parameterdef = this.Parameters[i]; - var parameterref = method.Parameters[i]; - - result = parameterdef.MatchReference(parameterref); - } - } - - return result; - } - public string ToSignatureString() { var result = new StringBuilder(); diff --git a/Model/Types/Types.cs b/Model/Types/Types.cs index 88e701e1..4a6f83f6 100644 --- a/Model/Types/Types.cs +++ b/Model/Types/Types.cs @@ -802,13 +802,28 @@ public ISet Attributes public int GenericParameterCount { - get { return 0; } + get { return GenericParameterCountOf(Type); } } public IBasicType ContainingType { get { return null; } } + + private int GenericParameterCountOf(IType type) + { + switch (Type.ElementsType) + { + case IGenericParameterReference genericParameterReference: + return genericParameterReference.GenericContainer.GenericParameterCount; + case ArrayType arrayType: + return GenericParameterCountOf(arrayType.ElementsType); + case PointerType pointerType: + return GenericParameterCountOf(pointerType.TargetType); + default: + return 0; + } + } } #endregion From dcf4f70a79e77b84255d917b7c4adaab70a7a7f6 Mon Sep 17 00:00:00 2001 From: fcurdi Date: Fri, 1 May 2020 16:58:14 -0300 Subject: [PATCH 10/14] missing import --- Backend/Utils/Helper.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Backend/Utils/Helper.cs b/Backend/Utils/Helper.cs index 3c0f2047..43d53039 100644 --- a/Backend/Utils/Helper.cs +++ b/Backend/Utils/Helper.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using Model; namespace Backend.Utils { From 4f5d8e060fc5cf04cdf329dce7a42755afe0f79b Mon Sep 17 00:00:00 2001 From: fcurdi Date: Mon, 25 May 2020 16:11:25 -0300 Subject: [PATCH 11/14] custom attributes --- MetadataProvider/AssemblyExtractor.cs | 34 +++++++++++++++++++ .../CustomAttributeTypeProvider.cs | 33 ++++++++++++++++++ MetadataProvider/MetadataProvider.csproj | 1 + Model/Types/Types.cs | 2 ++ 4 files changed, 70 insertions(+) create mode 100644 MetadataProvider/CustomAttributeTypeProvider.cs diff --git a/MetadataProvider/AssemblyExtractor.cs b/MetadataProvider/AssemblyExtractor.cs index 140f1d74..74fab308 100644 --- a/MetadataProvider/AssemblyExtractor.cs +++ b/MetadataProvider/AssemblyExtractor.cs @@ -28,6 +28,7 @@ internal class AssemblyExtractor private TypeDefinition currentType; private MethodDefinition currentMethod; private IDictionary currentMethodLocalVariablesNames; + private readonly CustomAttributeTypeProvider customAttributeTypeProvider; public AssemblyExtractor(Host host, SRPE.PEReader reader, SRM.MetadataReaderProvider pdbProvider = null) { @@ -40,6 +41,7 @@ public AssemblyExtractor(Host host, SRPE.PEReader reader, SRM.MetadataReaderProv this.defGenericContext = new GenericContext(); this.refGenericContext = new GenericContext(); this.signatureTypeProvider = new SignatureTypeProvider(this); + this.customAttributeTypeProvider = new CustomAttributeTypeProvider(signatureTypeProvider); if (pdbProvider != null) { @@ -248,6 +250,8 @@ private void ExtractType(SRM.TypeDefinitionHandle typedefHandle) { ExtractType(handle); } + + ExtractAttributes(type, typedef.GetCustomAttributes()); currentType = currentType.ContainingType; } @@ -445,6 +449,8 @@ private void ExtractField(SRM.FieldDefinitionHandle handle) field.IsStatic = fielddef.Attributes.HasFlag(SR.FieldAttributes.Static); field.Visibility = GetVisibilityKind(fielddef.Attributes); field.Value = ExtractFieldDefaultValue(fielddef); + + ExtractAttributes(field, fielddef.GetCustomAttributes()); currentType.Fields.Add(field); } @@ -487,6 +493,7 @@ private void ExtractProperty(SRM.PropertyDefinitionHandle handle) }; currentType.PropertyDefinitions.Add(property); BindGenericParameterReferences(GenericParameterKind.Type, currentType); + ExtractAttributes(property, propertyDef.GetCustomAttributes()); } private void ExtractMethod(SRM.MethodDefinitionHandle methoddefHandle, IList methodOverrides) @@ -526,6 +533,8 @@ private void ExtractMethod(SRM.MethodDefinitionHandle methoddefHandle, IList static, ldfld => not static) diff --git a/MetadataProvider/CustomAttributeTypeProvider.cs b/MetadataProvider/CustomAttributeTypeProvider.cs new file mode 100644 index 00000000..f196ad56 --- /dev/null +++ b/MetadataProvider/CustomAttributeTypeProvider.cs @@ -0,0 +1,33 @@ +using System.Reflection.Metadata; +using Model.Types; + +namespace MetadataProvider +{ + internal class CustomAttributeTypeProvider : ICustomAttributeTypeProvider + { + private readonly SignatureTypeProvider signatureTypeProvider; + + public CustomAttributeTypeProvider(SignatureTypeProvider signatureTypeProvider) + { + this.signatureTypeProvider = signatureTypeProvider; + } + + public IType GetPrimitiveType(PrimitiveTypeCode typeCode) => signatureTypeProvider.GetPrimitiveType(typeCode); + + public IType GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind) => + signatureTypeProvider.GetTypeFromDefinition(reader, handle, rawTypeKind); + + public IType GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind) => + signatureTypeProvider.GetTypeFromReference(reader, handle, rawTypeKind); + + public IType GetSZArrayType(IType elementType) => signatureTypeProvider.GetSZArrayType(elementType); + + public IType GetSystemType() => PlatformTypes.Type; + + public bool IsSystemType(IType type) => PlatformTypes.Type.Equals(type); + + public IType GetTypeFromSerializedName(string name) => new BasicType(name); + + public PrimitiveTypeCode GetUnderlyingEnumType(IType type) => PrimitiveTypeCode.Int32; + } +} \ No newline at end of file diff --git a/MetadataProvider/MetadataProvider.csproj b/MetadataProvider/MetadataProvider.csproj index 18c1c3a2..2f6ca308 100644 --- a/MetadataProvider/MetadataProvider.csproj +++ b/MetadataProvider/MetadataProvider.csproj @@ -49,6 +49,7 @@ + diff --git a/Model/Types/Types.cs b/Model/Types/Types.cs index 4a6f83f6..bfcf835a 100644 --- a/Model/Types/Types.cs +++ b/Model/Types/Types.cs @@ -81,6 +81,8 @@ public static class PlatformTypes public static readonly BasicType Task = New("mscorlib", "System.Threading.Tasks", "Task", TypeKind.ReferenceType); public static readonly BasicType GenericTask = New("mscorlib", "System.Threading.Tasks", "Task", TypeKind.ReferenceType, 1); + + public static readonly BasicType Type = New("mscorlib", "System", "Type", TypeKind.ReferenceType); public static void Resolve(Host host) { From eaeba991343a443bf8406b921aaed2edebc3a844 Mon Sep 17 00:00:00 2001 From: fcurdi Date: Sun, 5 Jul 2020 11:19:36 -0300 Subject: [PATCH 12/14] make property non nullable --- Model/ThreeAddressCode/Operands.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Model/ThreeAddressCode/Operands.cs b/Model/ThreeAddressCode/Operands.cs index 39ab1072..00128698 100644 --- a/Model/ThreeAddressCode/Operands.cs +++ b/Model/ThreeAddressCode/Operands.cs @@ -292,9 +292,7 @@ public class LocalVariable : IVariable public string Name { get; set; } public IType Type { get; set; } public bool IsParameter { get; set; } - - // int? because int defaults to 0 if not present - public int? Index { get; set; } + public int Index { get; set; } public LocalVariable(string name, bool isParameter = false) { From 267be9435c41eb7380243db5c9ae5528c7da77fe Mon Sep 17 00:00:00 2001 From: fcurdi Date: Wed, 5 Aug 2020 08:49:02 -0300 Subject: [PATCH 13/14] remove index --- MetadataProvider/AssemblyExtractor.cs | 9 +++------ Model/ThreeAddressCode/Operands.cs | 1 - 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/MetadataProvider/AssemblyExtractor.cs b/MetadataProvider/AssemblyExtractor.cs index 74fab308..394a8fe1 100644 --- a/MetadataProvider/AssemblyExtractor.cs +++ b/MetadataProvider/AssemblyExtractor.cs @@ -642,8 +642,7 @@ private void ExtractParameters(IList parameters) var v = new LocalVariable("this", true) { - Type = type, - Index = parameters.Count + Type = type }; parameters.Add(v); } @@ -652,8 +651,7 @@ private void ExtractParameters(IList parameters) { var v = new LocalVariable(parameter.Name, true) { - Type = parameter.Type, - Index = parameters.Count + Type = parameter.Type }; parameters.Add(v); @@ -672,8 +670,7 @@ private void ExtractLocalVariables(SRM.MethodBodyBlock bodyBlock, IList Date: Wed, 16 Dec 2020 21:08:01 -0300 Subject: [PATCH 14/14] read assembly attributes --- MetadataProvider/AssemblyExtractor.cs | 2 ++ Model/Assembly.cs | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/MetadataProvider/AssemblyExtractor.cs b/MetadataProvider/AssemblyExtractor.cs index 394a8fe1..5c40ca80 100644 --- a/MetadataProvider/AssemblyExtractor.cs +++ b/MetadataProvider/AssemblyExtractor.cs @@ -129,6 +129,8 @@ public Assembly Extract() Culture = metadata.GetString(assemblydef.Culture), PublicKey = metadata.GetBlobBytes(assemblydef.PublicKey) }; + + ExtractAttributes(assembly, assemblydef.GetCustomAttributes()); foreach (var handle in metadata.AssemblyReferences) { diff --git a/Model/Assembly.cs b/Model/Assembly.cs index c3fc6b29..9a52ebae 100644 --- a/Model/Assembly.cs +++ b/Model/Assembly.cs @@ -9,7 +9,7 @@ namespace Model { - public interface IAssemblyReference + public interface IAssemblyReference : IMetadataReference { string Name { get; } Version Version { get; } @@ -23,10 +23,11 @@ public class AssemblyReference : IAssemblyReference public Version Version { get; set; } public string Culture { get; set; } public byte[] PublicKey { get; set; } - + public ISet Attributes { get; private set; } public AssemblyReference(string name) { this.Name = name; + this.Attributes = new HashSet(); } public override string ToString() @@ -58,10 +59,12 @@ public class Assembly : IAssemblyReference public Version Version { get; set; } public string Culture { get; set; } public byte[] PublicKey { get; set; } + public ISet Attributes { get; private set; } public Assembly(string name) { this.Name = name; this.References = new List(); + this.Attributes = new HashSet(); } public bool MatchReference(IAssemblyReference reference)