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();
            }
        }
Example #2
0
        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();
            }
        }
Example #3
0
        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();
            }
        }
Example #4
0
        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();
            }
        }
        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();
            }
        }