示例#1
0
        /// <summary>
        /// Factory method for creating new Signatures.
        /// </summary>
        /// <param name="source">The contents of the library the signiture is being read from</param>
        /// <param name="offset">The offset to the start of the signiture</param>
        /// <param name="tokenType">The type of signiture being read.</param>
        /// <returns></returns>
        public static Signature Create(byte[] source, Offset offset, Signatures tokenType)
        {
            int  startingOffset    = offset;
            uint lengthOfSigniture = SignatureToken.GetCompressedValue(source, offset);    // The first byte is always the length

            // Read the full signiture
            byte[] signiture = new byte[lengthOfSigniture];
            for (int i = 0; i < lengthOfSigniture; i++)
            {
                signiture[i] = source[offset.Shift(1)];
            }

            // Instatiate the correct signiture reader and pass control
            Signature instantiatedSigniture = null;

            switch (tokenType)
            {
            case Signatures.CustomAttribute:     // instantiatedSigniture = new CustomAttributeSigniture(signiture); break;
            case Signatures.MethodSpecification: // to do: implement
                break;

            case Signatures.LocalVariable: instantiatedSigniture = new LocalVariableSignature(signiture); break;

            case Signatures.MethodDef: instantiatedSigniture = new MethodDefSignature(signiture); break;

            case Signatures.MethodRef: instantiatedSigniture = new MethodRefSignature(signiture); break;

            case Signatures.Field: instantiatedSigniture = new FieldSignature(signiture); break;

            case Signatures.Property: instantiatedSigniture = new PropertySignature(signiture); break;

            case Signatures.TypeSpecification: instantiatedSigniture = new TypeSpecificationSignature(signiture); break;
            }
            return(instantiatedSigniture);
        }
        /// <summary>
        /// Instantiates a new instance of the ElementTypeSignitureToken class.
        /// </summary>
        /// <include file='code-documentation\signatures.xml' path='docs/elementtypesignaturetoken/member[@name="ctor"]/*'/>
        public ElementTypeSignatureToken(byte[] signiture, Offset offset)
            : base(SignatureTokens.ElementType)
        {
            ElementType = (ElementTypes)GetCompressedValue(signiture, offset);

            switch (ElementType)
            {
            case ElementTypes.Class:
            case ElementTypes.ValueType:
                DecodeEncodedDefRefSpecToken(signiture, offset);
                break;

            case ElementTypes.MVar:
            case ElementTypes.Var:
                Token = SignatureToken.GetCompressedValue(signiture, offset);
                break;

            // Well known types
            case ElementTypes.Boolean: Definition = WellKnownTypeDef.Boolean; break;

            case ElementTypes.I: Definition = WellKnownTypeDef.I; break;

            case ElementTypes.I1: Definition = WellKnownTypeDef.I1; break;

            case ElementTypes.I2: Definition = WellKnownTypeDef.I2; break;

            case ElementTypes.I4: Definition = WellKnownTypeDef.I4; break;

            case ElementTypes.I8: Definition = WellKnownTypeDef.I8; break;

            case ElementTypes.U: Definition = WellKnownTypeDef.U; break;

            case ElementTypes.U1: Definition = WellKnownTypeDef.U1; break;

            case ElementTypes.U2: Definition = WellKnownTypeDef.U2; break;

            case ElementTypes.U4: Definition = WellKnownTypeDef.U4; break;

            case ElementTypes.U8: Definition = WellKnownTypeDef.U8; break;

            case ElementTypes.Char: Definition = WellKnownTypeDef.Char; break;

            case ElementTypes.R4: Definition = WellKnownTypeDef.R4; break;

            case ElementTypes.R8: Definition = WellKnownTypeDef.R8; break;

            case ElementTypes.TypedByRef: Definition = WellKnownTypeDef.TypedByRef; break;

            case ElementTypes.String: Definition = WellKnownTypeDef.String; break;

            case ElementTypes.Object: Definition = WellKnownTypeDef.Object; break;

            case ElementTypes.Void: Definition = WellKnownTypeDef.Void; break;
            }
        }
        internal TypeRef ResolveType(AssemblyDef assembly, ReflectedMember member)
        {
            SignatureToken token = Tokens.Last();

            if (token is TypeSignatureToken)
            {
                return(((TypeSignatureToken)token).ResolveType(assembly, member));
            }
            else
            {
                return(((ElementTypeSignatureToken)token).ResolveToken(assembly));
            }
        }
        public TypeDetails GetTypeDetails(ReflectedMember member)
        {
            TypeDetails    details = new TypeDetails();
            SignatureToken token   = Tokens.Last();

            if (token is TypeSignatureToken)
            {
                details = ((TypeSignatureToken)token).GetTypeDetails(member);
            }
            else
            {
                details.Type = ((ElementTypeSignatureToken)token).ResolveToken(member.Assembly);
            }

            return(details);
        }
示例#5
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;
            }
        }
        /// <summary>
        /// Instantiates a new instance of the ElementTypeSignitureToken class.
        /// </summary>
        /// <param name="signiture">The signiture where this token is defined.</param>
        /// <param name="offset">The current offset in the signiture to read the token.</param>
        /// <remarks>
        /// <para>
        /// An ElementTypeSignitureToken details the element of a Type signiture. These
        /// elements are defined in section 23.1.16 in ECMA 335. Where a type can contain
        /// multiple ElementTypeSignitureTokens each building up to reveal more information
        /// about the type. This class will only ever provide a single item of detail.
        /// </para>
        /// </remarks>
        public ElementTypeSignatureToken(byte[] signiture, Offset offset)
            : base(SignatureTokens.ElementType)
        {
            ElementType = (ElementTypes)GetCompressedValue(signiture, offset);
            int  typeMask;
            uint token;

            switch (ElementType)
            {
            case ElementTypes.Class:
                // Read the typedef, typeref or typespec token
                typeMask = 0x00000003;
                token    = GetCompressedValue(signiture, offset);
                switch (typeMask & token)
                {
                case 0:                                                // TypeDef
                    Token = token >> 2 | (int)ILMetadataToken.TypeDef; // (token & typeMask) | token >> 2;
                    break;

                case 1:                                                // TypeRef
                    Token = token >> 2 | (int)ILMetadataToken.TypeRef; //(token & typeMask) | token >> 2;
                    break;

                case 2:                                                 // TypeSpec
                    Token = token >> 2 | (int)ILMetadataToken.TypeSpec; // (token & typeMask) | token >> 2;
                    break;
                }
                break;

            case ElementTypes.ValueType:
                // Read the typedef, typeref or typespec token
                typeMask = 0x00000003;
                token    = GetCompressedValue(signiture, offset);
                switch (typeMask & token)
                {
                case 0:                                                // TypeDef
                    Token = token >> 2 | (int)ILMetadataToken.TypeDef; // (token & typeMask) | token >> 2;
                    break;

                case 1:                                                // TypeRef
                    Token = token >> 2 | (int)ILMetadataToken.TypeRef; //(token & typeMask) | token >> 2;
                    break;
                }
                break;

            case ElementTypes.MVar:
            case ElementTypes.Var:
                Token = SignatureToken.GetCompressedValue(signiture, offset);
                break;

            // Well known types
            case ElementTypes.Boolean: Definition = WellKnownTypeDef.Boolean; break;

            case ElementTypes.I: Definition = WellKnownTypeDef.I; break;

            case ElementTypes.I1: Definition = WellKnownTypeDef.I1; break;

            case ElementTypes.I2: Definition = WellKnownTypeDef.I2; break;

            case ElementTypes.I4: Definition = WellKnownTypeDef.I4; break;

            case ElementTypes.I8: Definition = WellKnownTypeDef.I8; break;

            case ElementTypes.U: Definition = WellKnownTypeDef.U; break;

            case ElementTypes.U1: Definition = WellKnownTypeDef.U1; break;

            case ElementTypes.U2: Definition = WellKnownTypeDef.U2; break;

            case ElementTypes.U4: Definition = WellKnownTypeDef.U4; break;

            case ElementTypes.U8: Definition = WellKnownTypeDef.U8; break;

            case ElementTypes.Char: Definition = WellKnownTypeDef.Char; break;

            case ElementTypes.R4: Definition = WellKnownTypeDef.R4; break;

            case ElementTypes.R8: Definition = WellKnownTypeDef.R8; break;

            case ElementTypes.TypedByRef: Definition = WellKnownTypeDef.TypedByRef; break;

            case ElementTypes.String: Definition = WellKnownTypeDef.String; break;

            case ElementTypes.Object: Definition = WellKnownTypeDef.Object; break;

            case ElementTypes.Void: Definition = WellKnownTypeDef.Void; break;
            }
        }