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)); } }
/// <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)); } }
/// <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); }