protected int GetHashCode(ITypeSignature obj, bool canIgnoreOwner) { int hashCode = 0x87478; while (obj != null) { hashCode += 0x7549 << ((int)obj.ElementCode + 1); switch (obj.ElementCode) { case TypeElementCode.FunctionPointer: { hashCode ^= GetHashCode(obj.GetFunctionPointer(), false); obj = null; } break; case TypeElementCode.GenericParameter: { bool isMethod; int position; obj.GetGenericParameter(out isMethod, out position); if (isMethod) { hashCode++; } hashCode += position; obj = null; } break; case TypeElementCode.GenericType: { hashCode ^= obj.GenericArguments.Count << 8; obj = obj.DeclaringType; } break; case TypeElementCode.DeclaringType: { if (obj.Name != null) { hashCode ^= obj.Name.GetHashCode(); } if (obj.Namespace != null) { hashCode ^= obj.Namespace.GetHashCode(); } obj = obj.EnclosingType; } break; default: { obj = obj.ElementType; } break; } } return(hashCode); }
private bool EqualsType(ITypeSignature x, ITypeSignature y, ICodeNode xGenericContext = null) { if (x == y) { return(true); } if (x == null || y == null) { return(false); } switch (x.ElementCode) { case TypeElementCode.Array: { if (y.ElementCode != TypeElementCode.Array) { return(false); } if (!SignatureComparer.EqualsArrayDimensions(x.ArrayDimensions, y.ArrayDimensions)) { return(false); } if (!EqualsType(x.ElementType, y.ElementType, xGenericContext)) { return(false); } return(true); } case TypeElementCode.ByRef: { if (y.ElementCode != TypeElementCode.ByRef) { return(false); } if (!EqualsType(x.ElementType, y.ElementType, xGenericContext)) { return(false); } return(true); } case TypeElementCode.CustomModifier: { if (y.ElementCode != TypeElementCode.CustomModifier) { return(false); } CustomModifierType xModifierType; var xModifier = x.GetCustomModifier(out xModifierType); CustomModifierType yModifierType; var yModifier = y.GetCustomModifier(out yModifierType); if (xModifierType != yModifierType) { return(false); } if (!EqualsType(x.ElementType, y.ElementType, xGenericContext)) { return(false); } if (!EqualsType(xModifier, yModifier)) { return(false); } return(true); } case TypeElementCode.FunctionPointer: { if (y.ElementCode != TypeElementCode.FunctionPointer) { return(false); } if (!EqualsMethod(x.GetFunctionPointer(), y.GetFunctionPointer())) { return(false); } return(true); } case TypeElementCode.GenericParameter: { bool xIsMethod; int xPosition; x.GetGenericParameter(out xIsMethod, out xPosition); if (xGenericContext != null) { var xGenericType = xGenericContext.GetGenericArgument(xIsMethod, xPosition); if (xGenericType != null) { return(EqualsType(xGenericType, y)); } } if (y.ElementCode != TypeElementCode.GenericParameter) { return(false); } bool yIsMethod; int yPosition; y.GetGenericParameter(out yIsMethod, out yPosition); if (xIsMethod != yIsMethod) { return(false); } if (xPosition != yPosition) { return(false); } return(true); } case TypeElementCode.GenericType: { if (y.ElementCode != TypeElementCode.GenericType) { return(false); } if (!EqualsType(x.DeclaringType, y.DeclaringType)) { return(false); } if (!EqualsTypes(x.GenericArguments, y.GenericArguments, xGenericContext)) { return(false); } return(true); } case TypeElementCode.Pinned: { if (y.ElementCode != TypeElementCode.Pinned) { return(false); } if (!EqualsType(x.ElementType, y.ElementType, xGenericContext)) { return(false); } return(true); } case TypeElementCode.Pointer: { if (y.ElementCode != TypeElementCode.Pointer) { return(false); } if (!EqualsType(x.ElementType, y.ElementType, xGenericContext)) { return(false); } return(true); } case TypeElementCode.DeclaringType: { if (x.Name != y.Name) { return(false); } if (x.Namespace != y.Namespace) { return(false); } if (!EqualsTypeOwner(x.Owner, y.Owner)) { return(false); } return(true); } default: throw new NotImplementedException(); } }
protected bool Equals(ITypeSignature x, ITypeSignature y, bool canIgnoreOwner) { if (x == y) { return(true); } if (x == null || y == null) { return(false); } if (x.ElementCode != y.ElementCode) { return(false); } switch (x.ElementCode) { case TypeElementCode.Array: { if (!EqualsArrayDimensions(x.ArrayDimensions, y.ArrayDimensions)) { return(false); } if (!Equals(x.ElementType, y.ElementType, canIgnoreOwner)) { return(false); } return(true); } case TypeElementCode.ByRef: { if (!Equals(x.ElementType, y.ElementType, canIgnoreOwner)) { return(false); } return(true); } case TypeElementCode.CustomModifier: { CustomModifierType xModifierType; var xModifier = x.GetCustomModifier(out xModifierType); CustomModifierType yModifierType; var yModifier = y.GetCustomModifier(out yModifierType); if (xModifierType != yModifierType) { return(false); } if (!Equals(x.ElementType, y.ElementType, canIgnoreOwner)) { return(false); } if (!Equals(xModifier, yModifier, false)) { return(false); } return(true); } case TypeElementCode.FunctionPointer: { if (!Equals(x.GetFunctionPointer(), y.GetFunctionPointer(), false)) { return(false); } return(true); } case TypeElementCode.GenericParameter: { bool xIsMethod; int xPosition; x.GetGenericParameter(out xIsMethod, out xPosition); bool yIsMethod; int yPosition; y.GetGenericParameter(out yIsMethod, out yPosition); if (xIsMethod != yIsMethod) { return(false); } if (xPosition != yPosition) { return(false); } return(true); } case TypeElementCode.GenericType: { if (!Equals(x.DeclaringType, y.DeclaringType, canIgnoreOwner)) { return(false); } if (!Equals(x.GenericArguments, y.GenericArguments, false)) { return(false); } return(true); } case TypeElementCode.Pinned: { if (!Equals(x.ElementType, y.ElementType, canIgnoreOwner)) { return(false); } return(true); } case TypeElementCode.Pointer: { if (!Equals(x.ElementType, y.ElementType, canIgnoreOwner)) { return(false); } return(true); } case TypeElementCode.DeclaringType: { if (x.Name != y.Name) { return(false); } if (x.Namespace != y.Namespace) { return(false); } if (!EqualsTypeOwner(x.Owner, y.Owner, canIgnoreOwner)) { return(false); } return(true); } default: throw new NotImplementedException(); } }
private void PrintType(ITypeSignature typeSig, IModule module, bool ignoreOwner) { switch (typeSig.ElementCode) { case TypeElementCode.Array: { PrintType(typeSig.ElementType, module, true); _builder.Append("["); int count = typeSig.ArrayDimensions.Count - 1; for (int i = 0; i < count; i++) { _builder.Append(","); } _builder.Append("]"); } break; case TypeElementCode.ByRef: { PrintType(typeSig.ElementType, module, true); _builder.Append("&"); } break; case TypeElementCode.CustomModifier: { PrintType(typeSig.ElementType, module, true); } break; case TypeElementCode.FunctionPointer: break; case TypeElementCode.GenericParameter: { bool isMethod; int position; typeSig.GetGenericParameter(out isMethod, out position); if (isMethod) { _builder.Append("!!"); } else { _builder.Append("!"); } _builder.Append(position); } break; case TypeElementCode.GenericType: { PrintDeclaringType(typeSig.DeclaringType, module); PrintGenericArguments(typeSig.GenericArguments, module); } break; case TypeElementCode.Pinned: { PrintType(typeSig.ElementType, module, true); } break; case TypeElementCode.Pointer: { PrintType(typeSig.ElementType, module, true); _builder.Append("*"); } break; case TypeElementCode.DeclaringType: { PrintDeclaringType(typeSig, module); } break; default: throw new InvalidOperationException(); } if (!ignoreOwner) { typeSig = typeSig.GetDeclaringType(); if (typeSig != null) { var owner = typeSig.ResolutionScope; if (owner != null) { _builder.Append(", "); PrintAssembly((IAssemblySignature)owner); } else if (module != null && module.IsPrimeModule) { _builder.Append(", "); PrintAssembly(module.Assembly); } } } }
private void WriteType(ref int pos, ITypeSignature type) { _blob.Write(ref pos, (byte)SignatureType.Type); _blob.Write(ref pos, (byte)type.ElementCode); switch (type.ElementCode) { case TypeElementCode.Array: { var arrayDimensions = type.ArrayDimensions; _blob.Write7BitEncodedInt(ref pos, arrayDimensions.Count); for (int i = 0; i < arrayDimensions.Count; i++) { var arrayDimension = arrayDimensions[i]; WriteArrayDimensionBound(ref pos, arrayDimension.LowerBound); WriteArrayDimensionBound(ref pos, arrayDimension.UpperBound); } _blob.Length += 4; WriteReferenced(ref pos, type.ElementType); } break; case TypeElementCode.ByRef: { _blob.Length += 4; WriteReferenced(ref pos, type.ElementType); } break; case TypeElementCode.CustomModifier: { CustomModifierType modifierType; ITypeSignature modifier = type.GetCustomModifier(out modifierType); _blob.Write(ref pos, (byte)modifierType); _blob.Length += 8; WriteReferenced(ref pos, modifier); WriteReferenced(ref pos, type.ElementType); } break; case TypeElementCode.FunctionPointer: { _blob.Length += 4; WriteReferenced(ref pos, type.GetFunctionPointer()); } break; case TypeElementCode.GenericParameter: { bool isMethod; int position; type.GetGenericParameter(out isMethod, out position); _blob.Write(ref pos, (bool)isMethod); _blob.Write7BitEncodedInt(ref pos, position); } break; case TypeElementCode.GenericType: { var genericArguments = type.GenericArguments; _blob.Write7BitEncodedInt(ref pos, genericArguments.Count); _blob.Length += (genericArguments.Count + 1) * 4; WriteReferenced(ref pos, genericArguments); WriteReferenced(ref pos, type.DeclaringType); } break; case TypeElementCode.Pinned: { _blob.Length += 4; WriteReferenced(ref pos, type.ElementType); } break; case TypeElementCode.Pointer: { _blob.Length += 4; WriteReferenced(ref pos, type.ElementType); } break; case TypeElementCode.DeclaringType: { WriteString(ref pos, type.Name); WriteString(ref pos, type.Namespace); _blob.Write(ref pos, (bool?)SignatureUtils.TryGetIsValueType(type)); var owner = type.Owner; if (owner != null) { _blob.Write(ref pos, true); _blob.Length += 4; WriteReferenced(ref pos, owner); } else { _blob.Write(ref pos, false); } } break; default: throw new NotImplementedException(); } }
private void PrintType(ITypeSignature typeSig, IModule module, bool ignoreOwner) { switch (typeSig.ElementCode) { case TypeElementCode.Array: { PrintType(typeSig.ElementType, module, ignoreOwner); PrintArrayDimensions(typeSig.ArrayDimensions); } break; case TypeElementCode.ByRef: { PrintType(typeSig.ElementType, module, ignoreOwner); _builder.Append("&"); } break; case TypeElementCode.CustomModifier: { PrintType(typeSig.ElementType, module, ignoreOwner); CustomModifierType modifierType; var modifier = typeSig.GetCustomModifier(out modifierType); if (modifier != null) { if (modifierType == CustomModifierType.ModOpt) { _builder.Append(" modopt("); } else { _builder.Append(" modreq("); } PrintType(modifier, module, false); _builder.Append(")"); } } break; case TypeElementCode.FunctionPointer: { var callSite = typeSig.GetFunctionPointer(); if (callSite.IsStatic) { _builder.Append("static "); } PrintMethodCallConv(callSite.CallConv); _builder.Append("*"); PrintMethodArguments(callSite.Arguments, callSite.VarArgIndex, module); _builder.Append(" : "); PrintType(callSite.ReturnType, module, false); } break; case TypeElementCode.GenericParameter: { bool isMethod; int position; typeSig.GetGenericParameter(out isMethod, out position); if (isMethod) { _builder.Append("!!"); } else { _builder.Append("!"); } _builder.Append(position); } break; case TypeElementCode.GenericType: { PrintDeclaringType(typeSig.DeclaringType, module, ignoreOwner); PrintGenericArguments(typeSig.GenericArguments, module); } break; case TypeElementCode.Pinned: { PrintType(typeSig.ElementType, module, ignoreOwner); _builder.Append(" pinned"); } break; case TypeElementCode.Pointer: { PrintType(typeSig.ElementType, module, ignoreOwner); _builder.Append("*"); } break; case TypeElementCode.DeclaringType: { if ((_flags & SignaturePrintingFlags.UsePrimitiveTypes) == SignaturePrintingFlags.UsePrimitiveTypes) { var typeCode = typeSig.GetTypeCode(module); if (typeCode != PrimitiveTypeCode.Undefined) { _builder.Append(PrimitiveTypeNames[(int)typeCode]); return; } } PrintDeclaringType(typeSig, module, ignoreOwner); } break; default: throw new InvalidOperationException(); } }
protected virtual IType ResolveType(ITypeSignature typeSig, IModule context, ICodeNode genericContext) { switch (typeSig.ElementCode) { case TypeElementCode.Array: { var elementType = ResolveType(typeSig.ElementType, context, genericContext); if (elementType == null) { return(null); } return(elementType.MakeArrayType(typeSig.ArrayDimensions)); } case TypeElementCode.ByRef: { var elementType = ResolveType(typeSig.ElementType, context, genericContext); if (elementType == null) { return(null); } return(elementType.MakeByRefType()); } case TypeElementCode.CustomModifier: { var elementType = ResolveType(typeSig.ElementType, context, genericContext); if (elementType == null) { return(null); } CustomModifierType modifierType; var modifierSig = typeSig.GetCustomModifier(out modifierType); var modifier = ResolveType(modifierSig, context, genericContext); return(elementType.MakeCustomModifierType(modifier, modifierType)); } case TypeElementCode.FunctionPointer: { var callSite = ResolveCallSite(typeSig.GetFunctionPointer(), context, genericContext); return(MakeFunctionPointerType(callSite)); } case TypeElementCode.GenericParameter: { bool isMethod; int position; typeSig.GetGenericParameter(out isMethod, out position); if (genericContext != null) { var type = genericContext.GetGenericArgument(isMethod, position); if (type != null) { return(type); } } return(MakeGenericParameterType(isMethod, position)); } case TypeElementCode.GenericType: { var declaringType = ResolveType(typeSig.DeclaringType, context, genericContext); if (declaringType == null) { return(null); } var genericArgumentSigs = typeSig.GenericArguments; if (genericArgumentSigs.Count == 0) { return(declaringType); } var genericArguments = ResolveTypes(genericArgumentSigs, context, genericContext); if (genericArguments == null) { return(null); } return(declaringType.MakeGenericType(genericArguments)); } case TypeElementCode.Pinned: { var elementType = ResolveType(typeSig.ElementType, context, genericContext); if (elementType == null) { return(null); } return(elementType.MakePinnedType()); } case TypeElementCode.Pointer: { var elementType = ResolveType(typeSig.ElementType, context, genericContext); if (elementType == null) { return(null); } return(elementType.MakePointerType()); } case TypeElementCode.DeclaringType: { return(ResolveDeclaringType(typeSig, context)); } default: throw new NotImplementedException(); } }