public TypeRef ResolveParameter(AssemblyDef assembly, ParamDef declaringParameter) { TypeRef typeRef = null; if (_isTypeSigniture) { TypeSignatureToken typeToken = Tokens.Last() as TypeSignatureToken; typeRef = typeToken.ResolveType(assembly, declaringParameter); } else { typeRef = _elementType.ResolveToken(assembly); } return(typeRef); }
/// <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; } }
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); }
/// <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); }
/// <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); }