/// <summary> /// Returns a signature that represents an instantiation of the generic type represented /// by this signature with its own type parameters as type arguments. /// </summary> /// <param name="typeParamCount">The number of type parameters in the generic type.</param> /// <returns>A <see cref="TypeSignature"/> representing the instantiation of the generic /// type whose definition is represented by this signature and whose type arguments are /// the generic type's own type parameters.</returns> /// <exception cref="ArgumentOutOfRangeException"><paramref name="typeParamCount"/> is zero or negative.</exception> /// <exception cref="InvalidOperationException">This signature does not represent a class or value /// type.</exception> public TypeSignature makeGenericSelfInstance(int typeParamCount) { if (typeParamCount <= 0) { throw new ArgumentOutOfRangeException(nameof(typeParamCount)); } byte firstByte = getFirstByte(); if (firstByte != (byte)SignatureTypeKind.Class && firstByte != (byte)SignatureTypeKind.ValueType) { throw new InvalidOperationException("Generic instantiation is only allowed for class or valuetype signatures."); } var builder = TypeSignatureBuilder.getInstance(); try { builder.appendByte((byte)SignatureTypeCode.GenericTypeInstance); builder.appendSignature(this); builder.appendCompressedUnsignedInt(typeParamCount); for (int i = 0; i < typeParamCount; i++) { builder.appendByte((byte)SignatureTypeCode.GenericTypeParameter); builder.appendCompressedUnsignedInt(i); } return(builder.makeSignature()); } finally { builder.clear(); } }
/// <summary> /// Returns a signature that represents an instantiation of the generic type represented /// by this signature. /// </summary> /// <param name="typeArguments">The type arguments of the instantiation.</param> /// <returns>A <see cref="TypeSignature"/> representing the instantiation of the generic /// type whose definition is represented by this signature and whose type arguments are /// given.</returns> /// <exception cref="ArgumentException"><paramref name="typeArguments"/> is empty.</exception> /// <exception cref="InvalidOperationException">This signature does not represent a class or value /// type.</exception> public TypeSignature makeGenericInstance(ReadOnlySpan <TypeSignature> typeArguments) { if (typeArguments.Length == 0) { throw new ArgumentException("Type arguments must not be empty.", nameof(typeArguments)); } byte firstByte = getFirstByte(); if (firstByte != (byte)SignatureTypeKind.Class && firstByte != (byte)SignatureTypeKind.ValueType) { throw new InvalidOperationException("Generic instantiation is only allowed for class and valuetype signatures."); } var builder = TypeSignatureBuilder.getInstance(); try { builder.appendByte((byte)SignatureTypeCode.GenericTypeInstance); builder.appendSignature(this); builder.appendCompressedUnsignedInt(typeArguments.Length); for (int i = 0; i < typeArguments.Length; i++) { builder.appendSignature(typeArguments[i]); } return(builder.makeSignature()); } finally { builder.clear(); } }
private TypeSignature _addTypeCodePrefix(SignatureTypeCode code) { if (isByRef()) { throw new InvalidOperationException("Cannot use a by-ref type as the element type of an array, pointer or by-ref type."); } int compactLength = (int)(m_compact >> 56); if (compactLength < 7) { return(new TypeSignature((long)(compactLength + 1) << 56 | m_compact << 8 | (byte)code)); } var builder = TypeSignatureBuilder.getInstance(); try { builder.appendByte((byte)code); builder.appendSignature(this); return(builder.makeSignature()); } finally { builder.clear(); } }
private static TypeSignature _forClassOrValueType(EntityHandle handle, bool isValueType) { if (handle.IsNil) { throw new ArgumentException("Handle for a class or value type must not be null.", nameof(handle)); } var builder = TypeSignatureBuilder.getInstance(); try { builder.appendByte((byte)(isValueType ? SignatureTypeKind.ValueType : SignatureTypeKind.Class)); builder.appendCompressedUnsignedInt(CodedIndex.TypeDefOrRefOrSpec(handle)); return(builder.makeSignature()); } finally { builder.clear(); } }
/// <summary> /// Returns a signature representing a general array type whose element type is represented /// by this signature. /// </summary> /// /// <param name="rank">The number of array dimensions.</param> /// <param name="lengths">A span containing the lengths for each dimension. The length of /// this argument must not be greater than <paramref name="rank"/>.</param> /// <param name="lowerBounds">A span containing the lower bounds for each dimension. The length of /// this argument must not be greater than <paramref name="rank"/>.</param> /// /// <returns>A <see cref="TypeSignature"/> representing the array type whose element type /// is represented by this signature and whose rank, lengths and lower bounds are given.</returns> /// /// <exception cref="InvalidOperationException">This signature represents a by-ref type.</exception> /// <exception cref="ArgumentOutOfRangeException">The rank is negative or zero, or the length /// of <paramref name="lengths"/> or <paramref name="lowerBounds"/> is greater than the rank.</exception> /// /// <remarks> /// This method creates a signature for a general array. To create a signature for a single-dimensional /// zero-based array, use <see cref="makeSZArray"/>. In particular, setting <paramref name="rank"/> /// to 1 and <paramref name="lengths"/> and <paramref name="lowerBounds"/> to empty spans does not /// create the same signature as <see cref="makeSZArray"/>. /// </remarks> public TypeSignature makeArray( int rank, ReadOnlySpan <int> lengths = default, ReadOnlySpan <int> lowerBounds = default) { if (rank <= 0) { throw new ArgumentOutOfRangeException(nameof(rank)); } if (lengths.Length > rank || lowerBounds.Length > rank) { throw new ArgumentOutOfRangeException("Number of lengths or lower bounds is greater than the array rank."); } if (isByRef()) { throw new InvalidOperationException("Cannot use a by-ref type as the element type of an array, pointer or by-ref type."); } var builder = TypeSignatureBuilder.getInstance(); try { builder.appendByte((byte)SignatureTypeCode.Array); builder.appendSignature(this); builder.appendCompressedUnsignedInt(rank); builder.appendCompressedUnsignedInt(lengths.Length); for (int i = 0; i < lengths.Length; i++) { builder.appendCompressedUnsignedInt(lengths[i]); } builder.appendCompressedUnsignedInt(lowerBounds.Length); for (int i = 0; i < lowerBounds.Length; i++) { builder.appendCompressedSignedInt(lowerBounds[i]); } return(builder.makeSignature()); } finally { builder.clear(); } }
/// <summary> /// Returns a signature representing the type parameter of a generic method at the /// given position. /// </summary> /// <param name="position">The zero-based position of the type parameter.</param> /// <returns>A <see cref="TypeSignature"/> representing the type parameter of a generic method at the /// given position.</returns> /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is zero or negative.</exception> public static TypeSignature forGenericMethodParam(int position) { if (position < 0) { throw new ArgumentOutOfRangeException(nameof(position)); } if (position < 127) { return(new TypeSignature( (2L << 56) | (long)(position << 8) | (byte)SignatureTypeCode.GenericMethodParameter)); } var builder = TypeSignatureBuilder.getInstance(); try { builder.appendByte((byte)SignatureTypeCode.GenericMethodParameter); builder.appendCompressedUnsignedInt(position); return(builder.makeSignature()); } finally { builder.clear(); } }