private void ReadReturnTypeSignature(Signature created, byte[] signature, Offset offset)
        {
            // p.265 of ecma 335

            // zero or more custom modifiers can be provided
            while (CustomModifierToken.IsToken(signature, offset))
            {
                created.Tokens.Add(new CustomModifierToken(signature, offset));
            }

            // byref path
            if (ElementTypeSignatureToken.IsToken(signature, offset, ElementTypes.ByRef))
            {
                created.Tokens.Add(new ElementTypeSignatureToken(signature, offset)); // ByRef
                created.Tokens.Add(new TypeSignatureToken(signature, offset));        // Type
            }
            // typed by ref or void path path
            else if (ElementTypeSignatureToken.IsToken(signature, offset, ElementTypes.Void | ElementTypes.TypedByRef))
            {
                created.Tokens.Add(new ElementTypeSignatureToken(signature, offset));    // Void, TypedByRef
            }
            // path for byref where byref is not provided
            else
            {
                created.Tokens.Add(new TypeSignatureToken(signature, offset));
            }
        }
Beispiel #2
0
        /// <summary>
        /// Initialises a new instance of the property signiture from the provided <paramref name="signiture"/>.
        /// </summary>
        /// <param name="signiture">The signiture blob.</param>
        public PropertySignature(byte[] signiture)
            : base(Signatures.Property)
        {
            Offset offset = 0;

            ElementTypeSignatureToken property = new ElementTypeSignatureToken(signiture, offset);

            Tokens.Add(property);

            ParameterCountSignatureToken paramCount = new ParameterCountSignatureToken(signiture, offset);

            Tokens.Add(paramCount);

            while (CustomModifierToken.IsToken(signiture, offset))
            {
                CustomModifierToken modifier = new CustomModifierToken(signiture, offset);
                Tokens.Add(modifier);
            }

            ElementTypeSignatureToken type = new ElementTypeSignatureToken(signiture, offset);

            Tokens.Add(type);

            for (int i = 0; i < paramCount.Count; i++)
            {
                ParamSignatureToken param = new ParamSignatureToken(signiture, offset);
                Tokens.Add(param);
            }
        }
        /// <summary>
        /// Initialises a new instance of the ParamSignitureToken class from the provided <paramref name="signiture"/>
        /// at the specified <paramref name="offset"/>.
        /// </summary>
        /// <param name="signiture">The contents of the signiture.</param>
        /// <param name="offset">The offset of the current token.</param>
        public ParamSignatureToken(byte[] signiture, Offset offset)
            : base(SignatureTokens.Param)
        {
            while (CustomModifierToken.IsToken(signiture, offset))
            {
                Tokens.Add(new CustomModifierToken(signiture, offset));
                HasCustomModifier = true;
            }

            // After a custom modifier the parameter can be defined as a ByRef, TypedByRef or Type token.
            if (ElementTypeSignatureToken.IsToken(signiture, offset, ElementTypes.ByRef))
            {
                Tokens.Add(new ElementTypeSignatureToken(signiture, offset)); // ByRef
                TypeSignatureToken typeSig = new TypeSignatureToken(signiture, offset);
                Tokens.Add(typeSig);                                          // Type
                _elementType     = typeSig.ElementType;
                _isTypeSigniture = true;
                IsByRef          = true;
            }
            else if (ElementTypeSignatureToken.IsToken(signiture, offset, ElementTypes.TypedByRef))
            {
                ElementTypeSignatureToken elementSig = new ElementTypeSignatureToken(signiture, offset);
                Tokens.Add(elementSig);    // Type
                _elementType = elementSig;
            }
            else
            {
                TypeSignatureToken typeSig = new TypeSignatureToken(signiture, offset);
                Tokens.Add(typeSig);
                _elementType     = typeSig.ElementType;
                _isTypeSigniture = true;
            }
        }
        /// <summary>
        /// Initialises a new TypeSigniture from the <paramref name="signiture"/> starting at the
        /// specified <paramref name="offset"/>.
        /// </summary>
        /// <param name="signiture">The signiture to parse the type from.</param>
        /// <param name="offset">The offset to start reading from.</param>
        public TypeSignatureToken(byte[] signiture, Offset offset)
            : base(SignatureTokens.Type)
        {
            ElementTypeSignatureToken type = new ElementTypeSignatureToken(signiture, offset);
            TypeSignatureToken        childType;

            Tokens.Add(type);
            ElementType = type;

            switch (type.ElementType)
            {
            case ElementTypes.SZArray:
                while (CustomModifierToken.IsToken(signiture, offset))
                {
                    CustomModifierToken modifier = new CustomModifierToken(signiture, offset);
                    Tokens.Add(modifier);
                }
                childType = new TypeSignatureToken(signiture, offset);
                Tokens.Add(childType);
                break;

            case ElementTypes.Ptr:
                while (CustomModifierToken.IsToken(signiture, offset))
                {
                    CustomModifierToken modifier = new CustomModifierToken(signiture, offset);
                    Tokens.Add(modifier);
                }
                childType = new TypeSignatureToken(signiture, offset);
                Tokens.Add(childType);
                break;

            case ElementTypes.GenericInstance:
                ElementTypeSignatureToken genericType = new ElementTypeSignatureToken(signiture, offset);
                Tokens.Add(genericType);
                GenericArgumentCountSignatureToken argCount = new GenericArgumentCountSignatureToken(signiture, offset);
                Tokens.Add(argCount);
                for (int i = 0; i < argCount.Count; i++)
                {
                    TypeSignatureToken genArgType = new TypeSignatureToken(signiture, offset);
                    Tokens.Add(genArgType);
                }
                break;

            case ElementTypes.Array:
                childType = new TypeSignatureToken(signiture, offset);
                Tokens.Add(childType);
                Tokens.Add(new ArrayShapeSignatureToken(signiture, offset));
                break;
            }
        }
        /// <summary>
        /// Initialise a new instance of a local variable signiture from the <paramref name="signiture"/>
        /// provided.
        /// </summary>
        /// <param name="signiture">The signiture blob.</param>
        internal LocalVariableSignature(byte[] signiture) : base(Signatures.LocalVariable)
        {
            Offset offset = 0;

            offset.Shift(1);    // jump passed the 0x7 indicator

            CountSignatureToken count = new CountSignatureToken(signiture, offset);

            Tokens.Add(count);

            for (int i = 0; i < count.Count; i++)
            {
                if (ElementTypeSignatureToken.IsToken(signiture, offset, ElementTypes.TypedByRef))
                {
                    ElementTypeSignatureToken typedByRef = new ElementTypeSignatureToken(signiture, offset);
                    Tokens.Add(typedByRef);
                }
                else
                {
                    while (CustomModifierToken.IsToken(signiture, offset) || ConstraintSignatureToken.IsToken(signiture, offset))
                    {
                        if (CustomModifierToken.IsToken(signiture, offset))
                        {
                            CustomModifierToken modifier = new CustomModifierToken(signiture, offset);
                            Tokens.Add(modifier);
                        }
                        else
                        {
                            ConstraintSignatureToken constraint = new ConstraintSignatureToken(signiture, offset);
                            Tokens.Add(constraint);
                        }
                    }

                    ElementTypeSignatureToken byRef = new ElementTypeSignatureToken(signiture, offset);
                    Tokens.Add(byRef);

                    ElementTypeSignatureToken type = new ElementTypeSignatureToken(signiture, offset);
                    Tokens.Add(type);
                }
            }
        }
        /// <summary>
        /// Initialises a new instance of the ReturnTypeSignitureToken class.
        /// </summary>
        /// <param name="signiture">The signiture to read.</param>
        /// <param name="offset">The offset to start processing at.</param>
        public ReturnTypeSignatureToken(byte[] signiture, Offset offset)
            : base(SignatureTokens.ReturnType)
        {
            while (CustomModifierToken.IsToken(signiture, offset))
            {
                Tokens.Add(new CustomModifierToken(signiture, offset));
            }

            if (ElementTypeSignatureToken.IsToken(signiture, offset, ElementTypes.ByRef))
            {
                Tokens.Add(new ElementTypeSignatureToken(signiture, offset)); // ByRef
                Tokens.Add(new TypeSignatureToken(signiture, offset));        // Type
            }
            else if (ElementTypeSignatureToken.IsToken(signiture, offset, ElementTypes.Void | ElementTypes.TypedByRef))
            {
                Tokens.Add(new ElementTypeSignatureToken(signiture, offset));    // Void, TypedByRef
            }
            else
            {
                Tokens.Add(new TypeSignatureToken(signiture, offset));
            }
        }
Beispiel #7
0
        /// <summary>
        /// Method which performs the actual conversion of a signiture to a cref string.
        /// </summary>
        /// <param name="sb">The string builder to hold the converted text</param>
        /// <param name="assembly">The assembly the current parameter is defined in</param>
        /// <param name="param">The parameter definition, required for token resolution</param>
        /// <param name="currentToken">The current token to converty</param>
        /// <param name="elementType">The type of element the token represents</param>
        /// <param name="resolvedType">The resolved type for this token.</param>
        private void Convert(StringBuilder sb, AssemblyDef assembly, ParamDef param, SignatureToken currentToken, ElementTypes elementType, TypeRef resolvedType)
        {
            StringBuilder convertedSigniture = sb;

            if (currentToken.TokenType == SignatureTokens.Param)
            {
                ParamSignatureToken paramToken = currentToken as ParamSignatureToken;
                SignatureToken      childToken = paramToken.Tokens[paramToken.Tokens.Count - 1];

                if (childToken.TokenType == SignatureTokens.Type)
                {
                    currentToken = childToken;
                    elementType  = ((TypeSignatureToken)childToken).ElementType.ElementType;
                }
                else
                {
                    currentToken = childToken;
                    elementType  = ((ElementTypeSignatureToken)childToken).ElementType;
                }
            }

            TypeSignatureToken        typeToken    = currentToken as TypeSignatureToken;
            ElementTypeSignatureToken elementToken = currentToken as ElementTypeSignatureToken;

            switch (elementType)
            {
            case ElementTypes.Var: ConvertVar(convertedSigniture, typeToken.ElementType.Token, param); break;

            case ElementTypes.MVar: ConvertMVar(convertedSigniture, typeToken.ElementType.Token, param); break;

            case ElementTypes.SZArray:
                // TODO: Fix the custom modifier section
                if (typeToken.Tokens[0] is CustomModifierToken)
                {
                    NotImplementedException ex = new NotImplementedException("Custom modifiers are not implemented on SZArray");
                    ex.Data["token"] = currentToken;
                    throw ex;
                }

                ElementTypes szArrayElementType;
                if (typeToken.Tokens[1].TokenType == SignatureTokens.Type)
                {
                    szArrayElementType = ((TypeSignatureToken)typeToken.Tokens[1]).ElementType.ElementType;
                }
                else
                {
                    szArrayElementType = ((ElementTypeSignatureToken)typeToken.Tokens[1]).ElementType;
                }

                Convert(
                    sb,
                    assembly,
                    param,
                    typeToken.Tokens[1],
                    szArrayElementType,
                    resolvedType);

                convertedSigniture.Append("[]");
                break;

            case ElementTypes.Array:
                ArrayShapeSignatureToken shape = typeToken.Tokens.Last() as ArrayShapeSignatureToken;
                ConvertArray(convertedSigniture, resolvedType, shape);
                break;

            case ElementTypes.GenericInstance:
                TypeRef genericType = ((ElementTypeSignatureToken)typeToken.Tokens[1]).ResolveToken(assembly);
                GetTypeName(convertedSigniture, genericType);

                GenericArgumentCountSignatureToken argsCount = typeToken.GetGenericArgumentCount();
                bool isFirstArgument = true;
                if (argsCount.Count > 0)
                {
                    sb.Append(GenericStart);
                    for (int j = 0; j < argsCount.Count; j++)
                    {
                        if (isFirstArgument)
                        {
                            isFirstArgument = false;
                        }
                        else
                        {
                            sb.Append(",");
                        }

                        TypeRef      argResolvedType;
                        ElementTypes elType;
                        if (typeToken.Tokens[j + 3].TokenType == SignatureTokens.ElementType)
                        {
                            ElementTypeSignatureToken gESig = (ElementTypeSignatureToken)typeToken.Tokens[j + 3];
                            argResolvedType = gESig.ResolveToken(assembly);
                            elType          = gESig.ElementType;
                        }
                        else
                        {
                            TypeSignatureToken gTSig = (TypeSignatureToken)typeToken.Tokens[j + 3];
                            argResolvedType = gTSig.ResolveType(assembly, param);
                            elType          = gTSig.ElementType.ElementType;
                        }

                        Convert(
                            sb,
                            assembly,
                            param,
                            typeToken.Tokens[j + 3],
                            elType,
                            argResolvedType);
                    }
                    sb.Append(GenericEnd);
                }
                break;

            case ElementTypes.Class:
            case ElementTypes.ValueType:
            case ElementTypes.Char:
            case ElementTypes.I:
            case ElementTypes.I1:
            case ElementTypes.I2:
            case ElementTypes.I4:
            case ElementTypes.I8:
            case ElementTypes.Object:
            case ElementTypes.R4:
            case ElementTypes.R4_HFA:
            case ElementTypes.R8:
            case ElementTypes.R8_HFA:
            case ElementTypes.String:
            case ElementTypes.U:
            case ElementTypes.U1:
            case ElementTypes.U2:
            case ElementTypes.U4:
            case ElementTypes.U8:
            case ElementTypes.TypedByRef:
            case ElementTypes.Boolean:
                GetTypeName(convertedSigniture, resolvedType);
                break;

            case ElementTypes.Ptr:
                GetTypeName(convertedSigniture, resolvedType);
                convertedSigniture.Append("*");
                break;

            case ElementTypes.FunctionPointer:
                NotImplementedException fnPtrEx = new NotImplementedException("Function Pointer is not implemented yet.");
                fnPtrEx.Data["token"] = currentToken;
                throw fnPtrEx;
            }
        }
Beispiel #8
0
        public TypeDetails GetTypeDetails(ReflectedMember member)
        {
            TypeDetails details = new TypeDetails();

            if (ElementType.ElementType == ElementTypes.SZArray)
            {
                TypeSignatureToken childType = Tokens.Last() as TypeSignatureToken;
                details.ArrayOf = childType.GetTypeDetails(member);
                details.IsArray = true;
            }
            else if (
                ElementType.ElementType == ElementTypes.Class ||
                ElementType.ElementType == ElementTypes.ValueType
                )
            {
                details.Type = ElementType.ResolveToken(member.Assembly);
            }
            else if (ElementType.ElementType == ElementTypes.GenericInstance)
            {
                ElementTypeSignatureToken childType = Tokens[1] as ElementTypeSignatureToken;
                details.Type = childType.ResolveToken(member.Assembly);
                details.IsGenericInstance = true;
                details.GenericParameters = new List <TypeDetails>();
                for (int i = 3; i < GetGenericArgumentCount().Count + 3; i++)
                {
                    if (Tokens[i].TokenType == SignatureTokens.Type)
                    {
                        details.GenericParameters.Add(
                            ((TypeSignatureToken)Tokens[i]).GetTypeDetails(member)
                            );
                    }
                    else
                    {
                        TypeDetails genericParameter = new TypeDetails();
                        genericParameter.Type = ((ElementTypeSignatureToken)Tokens[i]).ResolveToken(member.Assembly);
                        details.GenericParameters.Add(genericParameter);
                    }
                }
            }
            else if (ElementType.ElementType == ElementTypes.Ptr)
            {
                if (Tokens[1].TokenType == SignatureTokens.Type)
                {
                    TypeSignatureToken childType = Tokens[1] as TypeSignatureToken;
                    details = childType.GetTypeDetails(member);
                }
                else
                {
                    ElementTypeSignatureToken childType = Tokens[1] as ElementTypeSignatureToken;
                    details.Type = childType.ResolveToken(member.Assembly);
                }
                details.IsPointer = true;
            }
            else if (ElementType.ElementType == ElementTypes.Array)
            {
                if (Tokens[1].TokenType == SignatureTokens.Type)
                {
                    TypeSignatureToken childType = Tokens[1] as TypeSignatureToken;
                    details.ArrayOf = childType.GetTypeDetails(member);
                }
                else
                {
                    ElementTypeSignatureToken childType = Tokens[1] as ElementTypeSignatureToken;
                    details.ArrayOf      = new TypeDetails();
                    details.ArrayOf.Type = childType.ResolveToken(member.Assembly);
                }
                details.IsMultidemensionalArray = true;
                details.ArrayShape = (ArrayShapeSignatureToken)Tokens.Find(t => t.TokenType == SignatureTokens.ArrayShape);
            }
            else if (ElementType.ElementType == ElementTypes.MVar)
            {
                details.Type = ResolveType(member.Assembly, member);
            }
            else if (ElementType.ElementType == ElementTypes.Var)
            {
                details.Type = ResolveType(member.Assembly, member);
            }
            else if (ElementType.Definition != null)
            {
                details.Type = ElementType.Definition as TypeRef;
            }

            return(details);
        }
Beispiel #9
0
        /// <summary>
        /// Attempts to resolve the type.
        /// </summary>
        /// <param name="assembly"></param>
        /// <param name="parameter"></param>
        /// <returns></returns>
        internal TypeRef ResolveType(AssemblyDef assembly, ParamDef parameter)
        {
            TypeRef type = null;

            if (ElementType.ElementType == ElementTypes.SZArray)
            {
                TypeSignatureToken childType = Tokens.Last() as TypeSignatureToken;
                type = childType.ResolveType(assembly, parameter);
            }
            else if (
                ElementType.ElementType == ElementTypes.Class ||
                ElementType.ElementType == ElementTypes.ValueType
                )
            {
                type = (TypeRef)assembly.ResolveMetadataToken(ElementType.Token);
            }
            else if (ElementType.ElementType == ElementTypes.GenericInstance)
            {
                ElementTypeSignatureToken childType = Tokens[1] as ElementTypeSignatureToken;
                type = childType.ResolveToken(assembly);
            }
            else if (ElementType.ElementType == ElementTypes.Ptr)
            {
                if (Tokens[1].TokenType == SignatureTokens.Type)
                {
                    TypeSignatureToken childType = Tokens[1] as TypeSignatureToken;
                    type = childType.ResolveType(assembly, parameter);
                }
                else
                {
                    ElementTypeSignatureToken childType = Tokens[1] as ElementTypeSignatureToken;
                    type = childType.ResolveToken(assembly);
                }
            }
            else if (ElementType.ElementType == ElementTypes.Array)
            {
                if (Tokens[1].TokenType == SignatureTokens.Type)
                {
                    TypeSignatureToken childType = Tokens[1] as TypeSignatureToken;
                    type = childType.ResolveType(assembly, parameter);
                }
                else
                {
                    ElementTypeSignatureToken childType = (ElementTypeSignatureToken)this.Tokens[1];
                    type = childType.ResolveToken(assembly);
                }
            }
            else if (ElementType.ElementType == ElementTypes.MVar)
            {
                type = parameter.Method.GenericTypes[(int)ElementType.Token];
            }
            else if (ElementType.ElementType == ElementTypes.Var)
            {
                List <GenericTypeRef> genericParameters = ((TypeDef)parameter.Method.Type).GenericTypes;
                if (genericParameters.Count < ElementType.Token)
                {
                    throw new InvalidOperationException("The generic token refers to a parameter that is not available.");
                }
                type = genericParameters[(int)ElementType.Token];
            }
            else if (ElementType.Definition != null)
            {
                type = ElementType.Definition as TypeRef;
            }
            return(type);
        }
Beispiel #10
0
        /// <summary>
        /// Attempts to resolve the type.
        /// </summary>
        /// <param name="assembly"></param>
        /// <param name="member"></param>
        /// <returns></returns>
        internal TypeRef ResolveType(AssemblyDef assembly, ReflectedMember member)
        {
            TypeRef type = null;

            if (ElementType.ElementType == ElementTypes.SZArray)
            {
                TypeSignatureToken childType = (TypeSignatureToken)Tokens.Last();
                type = childType.ResolveType(assembly, member);
            }
            else if (
                ElementType.ElementType == ElementTypes.Class ||
                ElementType.ElementType == ElementTypes.ValueType
                )
            {
                type = (TypeRef)assembly.ResolveMetadataToken(ElementType.Token);
            }
            else if (ElementType.ElementType == ElementTypes.GenericInstance)
            {
                ElementTypeSignatureToken childType = (ElementTypeSignatureToken)Tokens[1];
                type = childType.ResolveToken(assembly);
            }
            else if (ElementType.ElementType == ElementTypes.Ptr)
            {
                if (Tokens[1].TokenType == SignatureTokens.Type)
                {
                    TypeSignatureToken childType = (TypeSignatureToken)Tokens[1];
                    type = childType.ResolveType(assembly, member);
                }
                else
                {
                    ElementTypeSignatureToken childType = (ElementTypeSignatureToken)Tokens[1];
                    type = childType.ResolveToken(assembly);
                }
            }
            else if (ElementType.ElementType == ElementTypes.Array)
            {
                if (Tokens[1].TokenType == SignatureTokens.Type)
                {
                    TypeSignatureToken childType = (TypeSignatureToken)Tokens[1];
                    type = childType.ResolveType(assembly, member);
                }
                else
                {
                    ElementTypeSignatureToken childType = (ElementTypeSignatureToken)Tokens[1];
                    type = childType.ResolveToken(assembly);
                }
            }
            else if (ElementType.ElementType == ElementTypes.MVar)
            {
                MethodDef method = member as MethodDef;
                if (method == null)
                {
                    InvalidOperationException ex = new InvalidOperationException(
                        string.Format(
                            "A MethodDef was expected for type resolution in the signiture but a {0} was provided.",
                            member.GetType().ToString()
                            ));
                    throw ex;
                }
                type = method.GenericTypes[(int)ElementType.Token];
            }
            else if (ElementType.ElementType == ElementTypes.Var)
            {
                // Anything that contains a Type property will do here
                TypeDef theType;
                if (member is MethodDef)
                {
                    // a method may define its own parameters
                    theType = (TypeDef)((MethodDef)member).Type;
                }
                else if (member is PropertyDef)
                {
                    theType = ((PropertyDef)member).OwningType;
                }
                else if (member is FieldDef)
                {
                    theType = (TypeDef)((FieldDef)member).Type;
                }
                else if (member is EventDef)
                {
                    theType = ((EventDef)member).Type;
                }
                else if (member is TypeSpec)
                {
                    theType = ((TypeSpec)member).ImplementingType;
                }
                else
                {
                    InvalidOperationException ex = new InvalidOperationException(
                        string.Format(
                            "A ReflectedMember that is contained by a TypeDef was expected for type resolution in the signiture but a {0} was provided.",
                            member.GetType().ToString()
                            ));
                    throw ex;
                }

                List <GenericTypeRef> genericParameters = theType.GenericTypes;

                if (genericParameters.Count < ElementType.Token)
                {
                    throw new InvalidOperationException("The generic token refers to a parameter that is not available.");
                }
                type = genericParameters[(int)ElementType.Token];
            }
            else if (ElementType.Definition != null)
            {
                type = (TypeRef)ElementType.Definition;
            }
            return(type);
        }