示例#1
0
        /// <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();
            }
        }
示例#2
0
        /// <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();
            }
        }
示例#3
0
        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();
            }
        }
示例#4
0
        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();
            }
        }
示例#5
0
        /// <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();
            }
        }
示例#6
0
        /// <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();
            }
        }