From: Buyaa Namnan Date: Fri, 12 May 2023 21:12:45 +0000 (-0700) Subject: Write generic method, write complex signatures like array/pointer/generics (#86026) X-Git-Tag: accepted/tizen/unified/riscv/20231226.055536~2255 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=35cbe111b86cdb0581c257f85490cdcca735cedf;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Write generic method, write complex signatures like array/pointer/generics (#86026) * Write generic method, write complex signatures like array/pointer/generics * Update src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MethodBuilderImpl.cs Co-authored-by: Jan Kotas * Update src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MethodBuilderImpl.cs --------- Co-authored-by: Jan Kotas --- diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeMethodBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeMethodBuilder.cs index bac45a0..ecf34b5 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeMethodBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeMethodBuilder.cs @@ -519,17 +519,18 @@ namespace System.Reflection.Emit if (m_inst != null) throw new InvalidOperationException(SR.InvalidOperation_GenericParametersAlreadySet); - for (int i = 0; i < names.Length; i++) - ArgumentNullException.ThrowIfNull(names[i], nameof(names)); - if (m_token != 0) throw new InvalidOperationException(SR.InvalidOperation_MethodBuilderBaked); - m_bIsGenMethDef = true; m_inst = new RuntimeGenericTypeParameterBuilder[names.Length]; for (int i = 0; i < names.Length; i++) - m_inst[i] = new RuntimeGenericTypeParameterBuilder(new RuntimeTypeBuilder(names[i], i, this)); + { + string name = names[i]; + ArgumentNullException.ThrowIfNull(name, nameof(names)); + m_inst[i] = new RuntimeGenericTypeParameterBuilder(new RuntimeTypeBuilder(name, i, this)); + } + m_bIsGenMethDef = true; return m_inst; } diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeTypeBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeTypeBuilder.cs index 80b871a..47b7191 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeTypeBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeTypeBuilder.cs @@ -1061,29 +1061,6 @@ namespace System.Reflection.Emit } } - public override Type MakePointerType() - { - return SymbolType.FormCompoundType("*", this, 0)!; - } - - public override Type MakeByRefType() - { - return SymbolType.FormCompoundType("&", this, 0)!; - } - - [RequiresDynamicCode("The code for an array of the specified type might not be available.")] - public override Type MakeArrayType() - { - return SymbolType.FormCompoundType("[]", this, 0)!; - } - - [RequiresDynamicCode("The code for an array of the specified type might not be available.")] - public override Type MakeArrayType(int rank) - { - string s = GetRankString(rank); - return SymbolType.FormCompoundType(s, this, 0)!; - } - #endregion #region ICustomAttributeProvider Implementation @@ -1157,13 +1134,6 @@ namespace System.Reflection.Emit return m_inst; } - [RequiresDynamicCode("The native code for this instantiation might not be available at runtime.")] - [RequiresUnreferencedCode("If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), trimming can't validate that the requirements of those annotations are met.")] - public override Type MakeGenericType(params Type[] typeArguments) - { - return TypeBuilderInstantiation.MakeGenericType(this, typeArguments); - } - public override Type[] GetGenericArguments() => m_inst ?? Type.EmptyTypes; // If a TypeBuilder is generic, it must be a generic type definition diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs index e3f3b9a..d6b0941 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs @@ -290,5 +290,35 @@ namespace System.Reflection.Emit => SetParentCore(parent); protected abstract void SetParentCore([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type? parent); + + public override Type MakePointerType() + { + return SymbolType.FormCompoundType("*", this, 0)!; + } + + public override Type MakeByRefType() + { + return SymbolType.FormCompoundType("&", this, 0)!; + } + + [RequiresDynamicCode("The code for an array of the specified type might not be available.")] + public override Type MakeArrayType() + { + return SymbolType.FormCompoundType("[]", this, 0)!; + } + + [RequiresDynamicCode("The code for an array of the specified type might not be available.")] + public override Type MakeArrayType(int rank) + { + string s = GetRankString(rank); + return SymbolType.FormCompoundType(s, this, 0)!; + } + + [RequiresDynamicCode("The native code for this instantiation might not be available at runtime.")] + [RequiresUnreferencedCode("If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), trimming can't validate that the requirements of those annotations are met.")] + public override Type MakeGenericType(params Type[] typeArguments) + { + return TypeBuilderInstantiation.MakeGenericType(this, typeArguments); + } } } diff --git a/src/libraries/System.Reflection.Emit/src/Resources/Strings.resx b/src/libraries/System.Reflection.Emit/src/Resources/Strings.resx index ad9a578..5ff83e0 100644 --- a/src/libraries/System.Reflection.Emit/src/Resources/Strings.resx +++ b/src/libraries/System.Reflection.Emit/src/Resources/Strings.resx @@ -168,4 +168,7 @@ SizeConst parameter must be specified for UnmanagedType.ByValTStr type. - + + The generic parameters are already defined on this MethodBuilder. + + \ No newline at end of file diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/GenericTypeParameterBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/GenericTypeParameterBuilderImpl.cs index 0176c5f..fbaa3af 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/GenericTypeParameterBuilderImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/GenericTypeParameterBuilderImpl.cs @@ -4,28 +4,38 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Globalization; +using System.Reflection.Metadata; namespace System.Reflection.Emit { internal sealed class GenericTypeParameterBuilderImpl : GenericTypeParameterBuilder { private readonly string _name; - private readonly TypeBuilderImpl _type; + private readonly TypeBuilder _type; private readonly int _genParamPosition; private GenericParameterAttributes _genParamAttributes; - private bool _isGenericMethodParameter; [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] private Type? _parent; internal List? _customAttributes; internal List? _interfaces; + private MethodBuilderImpl? _methodBuilder; + internal EntityHandle _parentHandle; - internal GenericTypeParameterBuilderImpl(string name, int genParamPosition, TypeBuilderImpl typeBuilder) + internal GenericTypeParameterBuilderImpl(string name, int genParamPosition, TypeBuilderImpl typeBuilder, EntityHandle parentHandle) { _name = name; _genParamPosition = genParamPosition; _type = typeBuilder; - _isGenericMethodParameter = false; + _parentHandle = parentHandle; + } + + public GenericTypeParameterBuilderImpl(string name, int genParamPosition, MethodBuilderImpl methodBuilder) + { + _name = name; + _genParamPosition = genParamPosition; + _methodBuilder = methodBuilder; + _type = methodBuilder.DeclaringType; } protected override void SetBaseTypeConstraintCore([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type? baseTypeConstraint) @@ -59,8 +69,8 @@ namespace System.Reflection.Emit public override Type[] GetGenericParameterConstraints() => _interfaces == null ? EmptyTypes : _interfaces.ToArray(); - public override bool IsGenericTypeParameter => !_isGenericMethodParameter; - public override bool IsGenericMethodParameter => _isGenericMethodParameter; + public override bool IsGenericTypeParameter => _methodBuilder is null; + public override bool IsGenericMethodParameter => _methodBuilder is not null; public override int GenericParameterPosition => _genParamPosition; public override GenericParameterAttributes GenericParameterAttributes => _genParamAttributes; public override string Name => _name; diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MethodBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MethodBuilderImpl.cs index 99cdace..dbf38bc 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MethodBuilderImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MethodBuilderImpl.cs @@ -3,24 +3,23 @@ using System.Buffers.Binary; using System.Collections.Generic; -using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Reflection.Metadata; -using System.Runtime.InteropServices; namespace System.Reflection.Emit { internal sealed class MethodBuilderImpl : MethodBuilder { - private readonly Type _returnType; - private readonly Type[]? _parameterTypes; + private Type _returnType; + private Type[]? _parameterTypes; private readonly ModuleBuilderImpl _module; private readonly string _name; private readonly CallingConventions _callingConventions; private readonly TypeBuilderImpl _declaringType; private MethodAttributes _attributes; private MethodImplAttributes _methodImplFlags; + private GenericTypeParameterBuilderImpl[]? _typeParameters; internal DllImportData? _dllImportData; internal List? _customAttributes; @@ -49,11 +48,43 @@ namespace System.Reflection.Emit _methodImplFlags = MethodImplAttributes.IL; } - internal BlobBuilder GetMethodSignatureBlob() => - MetadataSignatureHelper.MethodSignatureEncoder(_module, _parameterTypes, ReturnType, !IsStatic); + internal BlobBuilder GetMethodSignatureBlob() => MetadataSignatureHelper.MethodSignatureEncoder(_module, + _parameterTypes, ReturnType, GetSignatureConvention(_callingConventions), GetGenericArguments().Length, !IsStatic); + internal static SignatureCallingConvention GetSignatureConvention(CallingConventions callingConventions) + { + // TODO: find out and handle other SignatureCallingConvention scenarios + SignatureCallingConvention convention = SignatureCallingConvention.Default; + if ((callingConventions & CallingConventions.HasThis) != 0 || + (callingConventions & CallingConventions.ExplicitThis) != 0) + { + convention |= SignatureCallingConvention.ThisCall; + } + + if ((callingConventions & CallingConventions.VarArgs) != 0) + { + convention |= SignatureCallingConvention.VarArgs; + } + + return convention; + } protected override bool InitLocalsCore { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - protected override GenericTypeParameterBuilder[] DefineGenericParametersCore(params string[] names) => throw new NotImplementedException(); + protected override GenericTypeParameterBuilder[] DefineGenericParametersCore(params string[] names) + { + if (_typeParameters != null) + throw new InvalidOperationException(SR.InvalidOperation_GenericParametersAlreadySet); + + var typeParameters = new GenericTypeParameterBuilderImpl[names.Length]; + for (int i = 0; i < names.Length; i++) + { + string name = names[i]; + ArgumentNullException.ThrowIfNull(names, nameof(names)); + typeParameters[i] = new GenericTypeParameterBuilderImpl(name, i, this); + } + + return _typeParameters = typeParameters; + } + protected override ParameterBuilder DefineParameterCore(int position, ParameterAttributes attributes, string? strParamName) { if (position > 0 && (_parameterTypes == null || position > _parameterTypes.Length)) @@ -66,6 +97,7 @@ namespace System.Reflection.Emit _parameters[position] = parameter; return parameter; } + protected override ILGenerator GetILGeneratorCore(int size) => throw new NotImplementedException(); protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan binaryAttribute) { @@ -106,15 +138,32 @@ namespace System.Reflection.Emit _methodImplFlags = attributes; } protected override void SetSignatureCore(Type? returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers, Type[]? parameterTypes, - Type[][]? parameterTypeRequiredCustomModifiers, Type[][]? parameterTypeOptionalCustomModifiers) => throw new NotImplementedException(); + Type[][]? parameterTypeRequiredCustomModifiers, Type[][]? parameterTypeOptionalCustomModifiers) + { + if (returnType != null) + { + _returnType = returnType; + } + + if (parameterTypes != null) + { + _parameterTypes = new Type[parameterTypes.Length]; + _parameters = new ParameterBuilderImpl[parameterTypes.Length + 1]; // parameter 0 reserved for return type + for (int i = 0; i < parameterTypes.Length; i++) + { + ArgumentNullException.ThrowIfNull(_parameterTypes[i] = parameterTypes[i], nameof(parameterTypes)); + } + } + // TODO: Add support for other parameters: returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypeRequiredCustomModifiers and parameterTypeOptionalCustomModifiers + } public override string Name => _name; public override MethodAttributes Attributes => _attributes; public override CallingConventions CallingConvention => _callingConventions; public override TypeBuilder DeclaringType => _declaringType; public override Module Module => _module; - public override bool ContainsGenericParameters { get => throw new NotSupportedException(SR.NotSupported_DynamicModule); } - public override bool IsGenericMethod { get => throw new NotImplementedException(); } - public override bool IsGenericMethodDefinition { get => throw new NotImplementedException(); } + public override bool ContainsGenericParameters => throw new NotSupportedException(); + public override bool IsGenericMethod => _typeParameters != null; + public override bool IsGenericMethodDefinition => _typeParameters != null; public override bool IsSecurityCritical => true; public override bool IsSecuritySafeCritical => false; public override bool IsSecurityTransparent => false; @@ -131,11 +180,9 @@ namespace System.Reflection.Emit public override object[] GetCustomAttributes(Type attributeType, bool inherit) => throw new NotSupportedException(SR.NotSupported_DynamicModule); - public override Type[] GetGenericArguments() - => throw new NotImplementedException(); + public override Type[] GetGenericArguments() => _typeParameters ?? Type.EmptyTypes; - public override MethodInfo GetGenericMethodDefinition() - => throw new NotImplementedException(); + public override MethodInfo GetGenericMethodDefinition() => !IsGenericMethod ? throw new InvalidOperationException() : this; public override int GetHashCode() => throw new NotImplementedException(); diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs index 15cbe7c..a135ed2 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs @@ -119,6 +119,8 @@ namespace System.Reflection.Emit WriteCustomAttributes(_customAttributes, moduleHandle); + // All generic parameters for all types and methods should be written in specific order + List genericParams = new(); // Add each type definition to metadata table. foreach (TypeBuilderImpl typeBuilder in _typeDefinitions) { @@ -133,15 +135,9 @@ namespace System.Reflection.Emit if (typeBuilder.IsGenericType) { - foreach (GenericTypeParameterBuilderImpl gParam in typeBuilder.GenericTypeParameters) + foreach (GenericTypeParameterBuilderImpl param in typeBuilder.GenericTypeParameters) { - GenericParameterHandle handle = AddGenericTypeParameter(typeHandle, gParam); - WriteCustomAttributes(gParam._customAttributes, handle); - - foreach (Type constraint in gParam.GetGenericParameterConstraints()) - { - _metadataBuilder.AddGenericParameterConstraint(handle, GetTypeHandle(constraint)); - } + genericParams.Add(param); } } @@ -165,12 +161,26 @@ namespace System.Reflection.Emit } WriteCustomAttributes(typeBuilder._customAttributes, typeHandle); - WriteMethods(typeBuilder); + WriteMethods(typeBuilder, genericParams); WriteFields(typeBuilder); } + + // Now write all generic parameters in order + genericParams.Sort((x, y) => { + int primary = CodedIndex.TypeOrMethodDef(x._parentHandle).CompareTo(CodedIndex.TypeOrMethodDef(y._parentHandle)); + if (primary != 0) + return primary; + + return x.GenericParameterPosition.CompareTo(y.GenericParameterPosition); + }); + + foreach (GenericTypeParameterBuilderImpl param in genericParams) + { + AddGenericTypeParametersAndConstraintsCustomAttributes(param._parentHandle, param); + } } - private void WriteMethods(TypeBuilderImpl typeBuilder) + private void WriteMethods(TypeBuilderImpl typeBuilder, List genericParams) { foreach (MethodBuilderImpl method in typeBuilder._methodDefinitions) { @@ -178,6 +188,17 @@ namespace System.Reflection.Emit WriteCustomAttributes(method._customAttributes, methodHandle); _nextMethodDefRowId++; + if (method.IsGenericMethodDefinition) + { + Type[] gParams = method.GetGenericArguments(); + for (int i = 0; i < gParams.Length; i++) + { + GenericTypeParameterBuilderImpl param = (GenericTypeParameterBuilderImpl)gParams[i]; + param._parentHandle = methodHandle; + genericParams.Add(param); + } + } + if (method._parameters != null) { foreach (ParameterBuilderImpl parameter in method._parameters) @@ -289,13 +310,21 @@ namespace System.Reflection.Emit return handle; } - private GenericParameterHandle AddGenericTypeParameter(TypeDefinitionHandle typeHandle, GenericTypeParameterBuilderImpl gParam) => - _metadataBuilder.AddGenericParameter( - parent: typeHandle, + private void AddGenericTypeParametersAndConstraintsCustomAttributes(EntityHandle parentHandle, GenericTypeParameterBuilderImpl gParam) + { + GenericParameterHandle handle = _metadataBuilder.AddGenericParameter( + parent: parentHandle, attributes: gParam.GenericParameterAttributes, name: _metadataBuilder.GetOrAddString(gParam.Name), index: gParam.GenericParameterPosition); + WriteCustomAttributes(gParam._customAttributes, handle); + foreach (Type constraint in gParam.GetGenericParameterConstraints()) + { + _metadataBuilder.AddGenericParameterConstraint(handle, GetTypeHandle(constraint)); + } + } + private void AddDefaultValue(ParameterHandle parameterHandle, object? defaultValue) => _metadataBuilder.AddConstant(parent: parameterHandle, value: defaultValue); diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/SignatureHelper.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/SignatureHelper.cs index 7bdc5cf..5e00821 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/SignatureHelper.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/SignatureHelper.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Collections.Immutable; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; @@ -12,8 +13,7 @@ namespace System.Reflection.Emit internal static BlobBuilder FieldSignatureEncoder(Type fieldType, ModuleBuilderImpl module) { BlobBuilder fieldSignature = new(); - - WriteSignatureForType(new BlobEncoder(fieldSignature).FieldSignature(), fieldType, module); + WriteSignatureForType(new BlobEncoder(fieldSignature).Field().Type(), fieldType, module); return fieldSignature; } @@ -41,13 +41,14 @@ namespace System.Reflection.Emit return constructorSignature; } - internal static BlobBuilder MethodSignatureEncoder(ModuleBuilderImpl module, Type[]? parameters, Type? returnType, bool isInstance) + internal static BlobBuilder MethodSignatureEncoder(ModuleBuilderImpl module, Type[]? parameters, + Type? returnType, SignatureCallingConvention convention, int genParamCount, bool isInstance) { // Encoding return type and parameters. BlobBuilder methodSignature = new(); new BlobEncoder(methodSignature). - MethodSignature(isInstanceMethod: isInstance). + MethodSignature(convention: convention, genericParameterCount: genParamCount, isInstanceMethod: isInstance). Parameters((parameters == null) ? 0 : parameters.Length, out ReturnTypeEncoder retEncoder, out ParametersEncoder parEncoder); if (returnType != null && returnType != module.GetTypeFromCoreAssembly(CoreTypeId.Void)) @@ -72,10 +73,75 @@ namespace System.Reflection.Emit private static void WriteSignatureForType(SignatureTypeEncoder signature, Type type, ModuleBuilderImpl module) { + if (type.IsArray) + { + Type elementType = type.GetElementType()!; + int rank = type.GetArrayRank(); + if (rank == 1) + { + WriteSignatureForType(signature.SZArray(), elementType, module); + } + else + { + signature.Array(out SignatureTypeEncoder elTypeSignature, out ArrayShapeEncoder arrayEncoder); + WriteSimpleSignature(elTypeSignature, elementType, module); + arrayEncoder.Shape(type.GetArrayRank(), ImmutableArray.Create(), ImmutableArray.Create(new int[rank])); + } + } + else if (type.IsPointer) + { + WriteSignatureForType(signature.Pointer(), type.GetElementType()!, module); + } + else if (type.IsByRef) + { + signature.Builder.WriteByte((byte)SignatureTypeCode.ByReference); + WriteSignatureForType(signature, type.GetElementType()!, module); + } + else if (type.IsGenericType) + { + Type[] genericArguments = type.GetGenericArguments(); + + GenericTypeArgumentsEncoder encoder = signature.GenericInstantiation( + module.GetTypeHandle(type.GetGenericTypeDefinition()), genericArguments.Length, type.IsValueType); + foreach (Type gType in genericArguments) + { + if (gType.IsGenericMethodParameter) + { + encoder.AddArgument().GenericMethodTypeParameter(gType.GenericParameterPosition); + } + else if (gType.IsGenericParameter) + { + encoder.AddArgument().GenericTypeParameter(gType.GenericParameterPosition); + } + else + { + WriteSignatureForType(encoder.AddArgument(), gType, module); + } + } + } + else if (type.IsGenericMethodParameter) + { + signature.GenericMethodTypeParameter(type.GenericParameterPosition); + } + else if (type.IsGenericParameter) + { + signature.GenericTypeParameter(type.GenericParameterPosition); + } + else + { + WriteSimpleSignature(signature, type, module); + } + } + + private static void WriteSimpleSignature(SignatureTypeEncoder signature, Type type, ModuleBuilderImpl module) + { CoreTypeId? typeId = module.GetTypeIdFromCoreTypes(type); switch (typeId) { + case CoreTypeId.Void: + signature.Builder.WriteByte((byte)SignatureTypeCode.Void); + return; case CoreTypeId.Boolean: signature.Boolean(); return; @@ -125,7 +191,7 @@ namespace System.Reflection.Emit signature.String(); return; case CoreTypeId.TypedReference: - signature.Builder.WriteByte((byte)SignatureTypeCode.TypedReference); + signature.TypedReference(); return; } diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs index eea762e..828f3a0 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs @@ -91,16 +91,15 @@ namespace System.Reflection.Emit if (_typeParameters != null) throw new InvalidOperationException(); - _typeParameters = new GenericTypeParameterBuilderImpl[names.Length]; - + var typeParameters = new GenericTypeParameterBuilderImpl[names.Length]; for (int i = 0; i < names.Length; i++) { string name = names[i]; ArgumentNullException.ThrowIfNull(name, nameof(names)); - _typeParameters[i] = new GenericTypeParameterBuilderImpl(name, i, this); + typeParameters[i] = new GenericTypeParameterBuilderImpl(name, i, this, _handle); } - return _typeParameters; + return _typeParameters = typeParameters; } protected override FieldBuilder DefineInitializedDataCore(string name, byte[] data, FieldAttributes attributes) => throw new NotImplementedException(); @@ -320,14 +319,7 @@ namespace System.Reflection.Emit => throw new NotSupportedException(); [DynamicallyAccessedMembers(GetAllMembers)] public override MemberInfo[] GetMembers(BindingFlags bindingAttr) => throw new NotSupportedException(); - public override bool IsAssignableFrom([NotNullWhen(true)] Type? c) => throw new NotSupportedException(); - public override Type MakePointerType() => throw new NotSupportedException(); - public override Type MakeByRefType() => throw new NotSupportedException(); - [RequiresDynamicCode("The code for an array of the specified type might not be available.")] - public override Type MakeArrayType() => throw new NotSupportedException(); - [RequiresDynamicCode("The code for an array of the specified type might not be available.")] - public override Type MakeArrayType(int rank) => throw new NotSupportedException(); internal const DynamicallyAccessedMemberTypes GetAllMembers = DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | diff --git a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveWithVariousMembersTests.cs b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveWithVariousMembersTests.cs index c100984..ec9fa93 100644 --- a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveWithVariousMembersTests.cs +++ b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveWithVariousMembersTests.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Collections; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; @@ -98,18 +97,14 @@ namespace System.Reflection.Emit.Tests { using (TempFile file = TempFile.Create()) { - AssemblyBuilder assemblyBuilder = AssemblyTools.PopulateAssemblyBuilderAndSaveMethod( - s_assemblyName, null, typeof(string), out MethodInfo saveMethod); - ModuleBuilder mb = assemblyBuilder.DefineDynamicModule("My Module"); - TypeBuilder tb = mb.DefineType("TestInterface", TypeAttributes.Interface | TypeAttributes.Abstract); + TypeBuilder tb = CreateAssemblyAndDefineType(out AssemblyBuilder assemblyBuilder, out MethodInfo saveMethod); tb.DefineMethod("TestMethod", MethodAttributes.Public); - saveMethod.Invoke(assemblyBuilder, new object[] { file.Path }); Assembly assemblyFromDisk = AssemblyTools.LoadAssemblyFromPath(file.Path); Module moduleFromDisk = assemblyFromDisk.Modules.First(); - Assert.Equal("My Module", moduleFromDisk.ScopeName); + Assert.Equal("MyModule", moduleFromDisk.ScopeName); Assert.Equal(1, moduleFromDisk.GetTypes().Length); Type testType = moduleFromDisk.GetTypes()[0]; @@ -122,6 +117,13 @@ namespace System.Reflection.Emit.Tests } } + private static TypeBuilder CreateAssemblyAndDefineType(out AssemblyBuilder assemblyBuilder, out MethodInfo saveMethod) + { + assemblyBuilder = AssemblyTools.PopulateAssemblyBuilderAndSaveMethod(s_assemblyName, null, typeof(string), out saveMethod); + return assemblyBuilder.DefineDynamicModule("MyModule") + .DefineType("TestInterface", TypeAttributes.Interface | TypeAttributes.Abstract); + } + [Fact] public void AddInterfaceImplementationTest() { @@ -151,33 +153,57 @@ namespace System.Reflection.Emit.Tests } } - [Fact] - public void SaveGenericTypeParametersForAType() + public static IEnumerable TypeParameters() + { + yield return new object[] { new string[] { "TFirst", "TSecond", "TThird" } }; + yield return new object[] { new string[] { "TFirst" } }; + } + + [Theory] + [MemberData(nameof(TypeParameters))] + public void SaveGenericTypeParametersForAType(string[] typeParamNames) { using (TempFile file = TempFile.Create()) { - AssemblyBuilder assemblyBuilder = AssemblyTools.PopulateAssemblyBuilderAndSaveMethod( - s_assemblyName, null, typeof(string), out MethodInfo saveMethod); - ModuleBuilder mb = assemblyBuilder.DefineDynamicModule("My Module"); - TypeBuilder tb = mb.DefineType("TestInterface", TypeAttributes.Interface | TypeAttributes.Abstract); - string[] typeParamNames = new string[] { "TFirst", "TSecond", "TThird" }; + TypeBuilder tb = CreateAssemblyAndDefineType(out AssemblyBuilder assemblyBuilder, out MethodInfo saveMethod); + MethodBuilder method = tb.DefineMethod("TestMethod", MethodAttributes.Public); GenericTypeParameterBuilder[] typeParams = tb.DefineGenericParameters(typeParamNames); - typeParams[0].SetInterfaceConstraints(new Type[] { typeof(IAccess), typeof(INoMethod)}); - typeParams[1].SetCustomAttribute(new CustomAttributeBuilder(typeof(DynamicallyAccessedMembersAttribute).GetConstructor( - new Type[] { typeof(DynamicallyAccessedMemberTypes) }), new object[] { DynamicallyAccessedMemberTypes.PublicProperties })); - typeParams[2].SetBaseTypeConstraint(typeof(EmptyTestClass)); - typeParams[2].SetGenericParameterAttributes(GenericParameterAttributes.VarianceMask); + if (typeParams.Length > 2) + { + SetVariousGenericParameterValues(typeParams); + } saveMethod.Invoke(assemblyBuilder, new object[] { file.Path }); - Assembly assemblyFromDisk = AssemblyTools.LoadAssemblyFromPath(file.Path); - Type testType = assemblyFromDisk.Modules.First().GetTypes()[0]; + Type testType = AssemblyTools.LoadAssemblyFromPath(file.Path).Modules.First().GetTypes()[0]; + MethodInfo testMethod = testType.GetMethod("TestMethod"); Type[] genericTypeParams = testType.GetGenericArguments(); - - Assert.Equal(3, genericTypeParams.Length); - Assert.Equal("TFirst", genericTypeParams[0].Name); + + Assert.True(testType.IsGenericType); + Assert.True(testType.IsGenericTypeDefinition); + Assert.True(testType.ContainsGenericParameters); + Assert.False(testMethod.IsGenericMethod); + Assert.False(testMethod.IsGenericMethodDefinition); + Assert.True(testMethod.ContainsGenericParameters); + AssertGenericParameters(typeParams, genericTypeParams); + } + } + + private static void SetVariousGenericParameterValues(GenericTypeParameterBuilder[] typeParams) + { + typeParams[0].SetInterfaceConstraints(new Type[] { typeof(IAccess), typeof(INoMethod) }); + typeParams[1].SetCustomAttribute(new CustomAttributeBuilder(typeof(DynamicallyAccessedMembersAttribute).GetConstructor( + new Type[] { typeof(DynamicallyAccessedMemberTypes) }), new object[] { DynamicallyAccessedMemberTypes.PublicProperties })); + typeParams[2].SetBaseTypeConstraint(typeof(EmptyTestClass)); + typeParams[2].SetGenericParameterAttributes(GenericParameterAttributes.VarianceMask); + } + + private static void AssertGenericParameters(GenericTypeParameterBuilder[] typeParams, Type[] genericTypeParams) + { + Assert.Equal("TFirst", genericTypeParams[0].Name); + if (typeParams.Length > 2) + { Assert.Equal("TSecond", genericTypeParams[1].Name); Assert.Equal("TThird", genericTypeParams[2].Name); - Type[] constraints = genericTypeParams[0].GetTypeInfo().GetGenericParameterConstraints(); Assert.Equal(2, constraints.Length); Assert.Equal(typeof(IAccess).FullName, constraints[0].FullName); @@ -188,7 +214,6 @@ namespace System.Reflection.Emit.Tests Assert.Equal(typeof(EmptyTestClass).FullName, constraints2[0].FullName); Assert.Equal(GenericParameterAttributes.None, genericTypeParams[0].GenericParameterAttributes); Assert.Equal(GenericParameterAttributes.VarianceMask, genericTypeParams[2].GenericParameterAttributes); - IList attributes = genericTypeParams[1].GetCustomAttributesData(); Assert.Equal(1, attributes.Count); Assert.Equal("DynamicallyAccessedMembersAttribute", attributes[0].AttributeType.Name); @@ -196,6 +221,262 @@ namespace System.Reflection.Emit.Tests Assert.Empty(genericTypeParams[0].GetCustomAttributesData()); } } + + [Theory] + [MemberData(nameof(TypeParameters))] + public void SaveGenericTypeParametersForAMethod(string[] typeParamNames) + { + using (TempFile file = TempFile.Create()) + { + TypeBuilder tb = CreateAssemblyAndDefineType(out AssemblyBuilder assemblyBuilder, out MethodInfo saveMethod); + MethodBuilder method = tb.DefineMethod("TestMethod", MethodAttributes.Public); + GenericTypeParameterBuilder[] typeParams = method.DefineGenericParameters(typeParamNames); + if (typeParams.Length > 2) + { + SetVariousGenericParameterValues(typeParams); + } + saveMethod.Invoke(assemblyBuilder, new object[] { file.Path }); + + Type testType = AssemblyTools.LoadAssemblyFromPath(file.Path).Modules.First().GetTypes()[0]; + MethodInfo testMethod = testType.GetMethod("TestMethod"); + Type[] genericTypeParams = testMethod.GetGenericArguments(); + + Assert.False(testType.IsGenericType); + Assert.False(testType.IsGenericTypeDefinition); + Assert.False(testType.ContainsGenericParameters); + Assert.True(testMethod.IsGenericMethod); + Assert.True(testMethod.IsGenericMethodDefinition); + Assert.True(testMethod.ContainsGenericParameters); + AssertGenericParameters(typeParams, genericTypeParams); + } + } + + [Theory] + [InlineData(0, "TestInterface[]")] + [InlineData(1, "TestInterface[]")] // not [*] + [InlineData(2, "TestInterface[,]")] + [InlineData(3, "TestInterface[,,]")] + public void SaveArrayTypeSignature(int rank, string name) + { + using (TempFile file = TempFile.Create()) + { + TypeBuilder tb = CreateAssemblyAndDefineType(out AssemblyBuilder assemblyBuilder, out MethodInfo saveMethod); + Type arrayType = rank == 0 ? tb.MakeArrayType() : tb.MakeArrayType(rank); + MethodBuilder mb = tb.DefineMethod("TestMethod", MethodAttributes.Public); + mb.SetReturnType(arrayType); + mb.SetParameters(new Type[] { typeof(INoMethod), arrayType, typeof(int[,,,]) }); + saveMethod.Invoke(assemblyBuilder, new object[] { file.Path }); + + Type testType = AssemblyTools.LoadAssemblyFromPath(file.Path).Modules.First().GetTypes()[0]; + MethodInfo testMethod = testType.GetMethod("TestMethod"); + Type intArray = testMethod.GetParameters()[2].ParameterType; + + Assert.False(testMethod.GetParameters()[0].ParameterType.IsSZArray); + Assert.True(intArray.IsArray); + Assert.Equal(4, intArray.GetArrayRank()); + Assert.Equal("Int32[,,,]", intArray.Name); + AssertArrayTypeSignature(rank, name, testMethod.ReturnType); + AssertArrayTypeSignature(rank, name, testMethod.GetParameters()[1].ParameterType); + } + } + + private static void AssertArrayTypeSignature(int rank, string name, Type arrayType) + { + Assert.True(rank < 2 ? arrayType.IsSZArray : arrayType.IsArray); + rank = rank == 0 ? rank + 1 : rank; + Assert.Equal(rank, arrayType.GetArrayRank()); + Assert.Equal(name, arrayType.Name); + } + + [Fact] + public void SaveByRefTypeSignature() + { + using (TempFile file = TempFile.Create()) + { + TypeBuilder tb = CreateAssemblyAndDefineType(out AssemblyBuilder assemblyBuilder, out MethodInfo saveMethod); + Type byrefType = tb.MakeByRefType(); + MethodBuilder mb = tb.DefineMethod("TestMethod", MethodAttributes.Public); + mb.SetReturnType(byrefType); + mb.SetParameters(new Type[] { typeof(INoMethod), byrefType }); + saveMethod.Invoke(assemblyBuilder, new object[] { file.Path }); + + Type testType = AssemblyTools.LoadAssemblyFromPath(file.Path).Modules.First().GetTypes()[0]; + MethodInfo testMethod = testType.GetMethod("TestMethod"); + + Assert.False(testMethod.GetParameters()[0].ParameterType.IsByRef); + AssertByRefType(testMethod.GetParameters()[1].ParameterType); + AssertByRefType(testMethod.ReturnType); + } + } + + private static void AssertByRefType(Type byrefParam) + { + Assert.True(byrefParam.IsByRef); + Assert.Equal("TestInterface&", byrefParam.Name); + } + + [Fact] + public void SavePointerTypeSignature() + { + using (TempFile file = TempFile.Create()) + { + TypeBuilder tb = CreateAssemblyAndDefineType(out AssemblyBuilder assemblyBuilder, out MethodInfo saveMethod); + Type pointerType = tb.MakePointerType(); + MethodBuilder mb = tb.DefineMethod("TestMethod", MethodAttributes.Public); + mb.SetReturnType(pointerType); + mb.SetParameters(new Type[] { typeof(INoMethod), pointerType }); + saveMethod.Invoke(assemblyBuilder, new object[] { file.Path }); + + Type testType = AssemblyTools.LoadAssemblyFromPath(file.Path).Modules.First().GetTypes()[0]; + MethodInfo testMethod = testType.GetMethod("TestMethod"); + + Assert.False(testMethod.GetParameters()[0].ParameterType.IsPointer); + AssertPointerType(testMethod.GetParameters()[1].ParameterType); + AssertPointerType(testMethod.ReturnType); + } + } + + private void AssertPointerType(Type testType) + { + Assert.True(testType.IsPointer); + Assert.Equal("TestInterface*", testType.Name); + } + + public static IEnumerable SaveGenericType_TestData() + { + yield return new object[] { new string[] { "U", "T" }, new Type[] { typeof(string), typeof(int) }, "TestInterface[System.String,System.Int32]" }; + yield return new object[] { new string[] { "U", "T" }, new Type[] { typeof(MakeGenericTypeClass), typeof(MakeGenericTypeInterface) }, + "TestInterface[System.Reflection.Emit.Tests.MakeGenericTypeClass,System.Reflection.Emit.Tests.MakeGenericTypeInterface]" }; + yield return new object[] { new string[] { "U" }, new Type[] { typeof(List) }, "TestInterface[System.Collections.Generic.List`1[System.String]]" }; + } + + [Theory] + [MemberData(nameof(SaveGenericType_TestData))] + public void SaveGenericTypeSignature(string[] genericParams, Type[] typeArguments, string stringRepresentation) + { + using (TempFile file = TempFile.Create()) + { + TypeBuilder tb = CreateAssemblyAndDefineType(out AssemblyBuilder assemblyBuilder, out MethodInfo saveMethod); + GenericTypeParameterBuilder[] typeGenParam = tb.DefineGenericParameters(genericParams); + Type genericType = tb.MakeGenericType(typeArguments); + MethodBuilder mb = tb.DefineMethod("TestMethod", MethodAttributes.Public); + mb.SetReturnType(genericType); + mb.SetParameters(new Type[] { typeof(INoMethod), genericType }); + saveMethod.Invoke(assemblyBuilder, new object[] { file.Path }); + + Type testType = AssemblyTools.LoadAssemblyFromPath(file.Path).Modules.First().GetTypes()[0]; + MethodInfo testMethod = testType.GetMethod("TestMethod"); + Type paramType = testMethod.GetParameters()[1].ParameterType; + + Assert.False(testMethod.GetParameters()[0].ParameterType.IsGenericType); + AssertGenericType(stringRepresentation, paramType); + AssertGenericType(stringRepresentation, testMethod.ReturnType); + } + } + + private static void AssertGenericType(string stringRepresentation, Type paramType) + { + Assert.True(paramType.IsGenericType); + Assert.Equal(stringRepresentation, paramType.ToString()); + Assert.False(paramType.IsGenericParameter); + Assert.False(paramType.IsGenericTypeDefinition); + Assert.False(paramType.IsGenericTypeParameter); + Assert.False(paramType.IsGenericMethodParameter); + } + + [Fact] + public void SaveGenericTypeSignatureWithGenericParameter() + { + using (TempFile file = TempFile.Create()) + { + TypeBuilder tb = CreateAssemblyAndDefineType(out AssemblyBuilder assemblyBuilder, out MethodInfo saveMethod); + GenericTypeParameterBuilder[] typeParams = tb.DefineGenericParameters(new string[] { "U", "T", "P" }); + MethodBuilder mb = tb.DefineMethod("TestMethod", MethodAttributes.Public); + GenericTypeParameterBuilder[] methodParams = mb.DefineGenericParameters(new string[] { "M", "N" }); + Type genericType = tb.MakeGenericType(typeParams); + mb.SetReturnType(methodParams[0]); + mb.SetParameters(new Type[] { typeof(INoMethod), genericType, typeParams[1] }); + saveMethod.Invoke(assemblyBuilder, new object[] { file.Path }); + + Type testType = AssemblyTools.LoadAssemblyFromPath(file.Path).Modules.First().GetTypes()[0]; + MethodInfo testMethod = testType.GetMethod("TestMethod"); + Type paramType = testMethod.GetParameters()[1].ParameterType; + Type genericParameter = testMethod.GetParameters()[2].ParameterType; + + Assert.False(testMethod.GetParameters()[0].ParameterType.IsGenericType); + AssertGenericType("TestInterface[U,T,P]", paramType); + Assert.False(genericParameter.IsGenericType); + Assert.True(genericParameter.IsGenericParameter); + Assert.False(genericParameter.IsGenericTypeDefinition); + Assert.True(genericParameter.IsGenericTypeParameter); + Assert.False(genericParameter.IsGenericMethodParameter); + Assert.Equal("T", genericParameter.Name); + Assert.False(testMethod.ReturnType.IsGenericType); + Assert.True(testMethod.ReturnType.IsGenericParameter); + Assert.False(testMethod.ReturnType.IsGenericTypeDefinition); + Assert.False(testMethod.ReturnType.IsGenericTypeParameter); + Assert.True(testMethod.ReturnType.IsGenericMethodParameter); + Assert.Equal("M", testMethod.ReturnType.Name); + } + } + + [Fact] + public void SaveMultipleGenericTypeParametersToEnsureSortingWorks() + { + using (TempFile file = TempFile.Create()) + { + AssemblyBuilder assemblyBuilder = AssemblyTools.PopulateAssemblyBuilderAndSaveMethod( + s_assemblyName, null, typeof(string), out MethodInfo saveMethod); + ModuleBuilder mb = assemblyBuilder.DefineDynamicModule("My Module"); + TypeBuilder tb = mb.DefineType("TestInterface1", TypeAttributes.Interface | TypeAttributes.Abstract); + GenericTypeParameterBuilder[] typeParams = tb.DefineGenericParameters(new string[] { "U", "T" }); + typeParams[1].SetInterfaceConstraints(new Type[] { typeof(INoMethod), typeof(IOneMethod) }); + MethodBuilder m11 = tb.DefineMethod("TwoParameters", MethodAttributes.Public); + MethodBuilder m12 = tb.DefineMethod("FiveTypeParameters", MethodAttributes.Public); + MethodBuilder m13 = tb.DefineMethod("OneParameter", MethodAttributes.Public); + m11.DefineGenericParameters(new string[] { "M", "N" }); + GenericTypeParameterBuilder[] methodParams = m12.DefineGenericParameters(new string[] { "A", "B", "C", "D", "F" }); + methodParams[2].SetInterfaceConstraints(new Type[] { typeof(IMultipleMethod) }); + m13.DefineGenericParameters(new string[] { "T" }); + TypeBuilder tb2 = mb.DefineType("TestInterface2", TypeAttributes.Interface | TypeAttributes.Abstract); + tb2.DefineGenericParameters(new string[] { "TFirst", "TSecond", "TThird" }); + MethodBuilder m21 = tb2.DefineMethod("TestMethod", MethodAttributes.Public); + m21.DefineGenericParameters(new string[] { "X", "Y", "Z" }); + TypeBuilder tb3 = mb.DefineType("TestType"); + GenericTypeParameterBuilder[] typePar = tb3.DefineGenericParameters(new string[] { "TOne" }); + typePar[0].SetBaseTypeConstraint(typeof(EmptyTestClass)); + saveMethod.Invoke(assemblyBuilder, new object[] { file.Path }); + + Module m = AssemblyTools.LoadAssemblyFromPath(file.Path).Modules.First(); + Type[] type1Params = m.GetTypes()[0].GetGenericArguments(); + Type[] type2Params = m.GetTypes()[1].GetGenericArguments(); + Type[] type3Params = m.GetTypes()[2].GetGenericArguments(); + + Assert.Equal("U", type1Params[0].Name); + Assert.Empty(type1Params[0].GetTypeInfo().GetGenericParameterConstraints()); + Assert.Equal("T", type1Params[1].Name); + Assert.Equal(nameof(IOneMethod), type1Params[1].GetTypeInfo().GetGenericParameterConstraints()[1].Name); + Assert.Equal("TFirst", type2Params[0].Name); + Assert.Equal("TSecond", type2Params[1].Name); + Assert.Equal("TThird", type2Params[2].Name); + Assert.Equal("TOne", type3Params[0].Name); + Assert.Equal(nameof(EmptyTestClass), type3Params[0].GetTypeInfo().GetGenericParameterConstraints()[0].Name); + + Type[] method11Params = m.GetTypes()[0].GetMethod("TwoParameters").GetGenericArguments(); + Type[] method12Params = m.GetTypes()[0].GetMethod("FiveTypeParameters").GetGenericArguments(); + Assert.Equal(nameof(IMultipleMethod), method12Params[2].GetTypeInfo().GetGenericParameterConstraints()[0].Name); + Type[] method13Params = m.GetTypes()[0].GetMethod("OneParameter").GetGenericArguments(); + Type[] method21Params = m.GetTypes()[1].GetMethod("TestMethod").GetGenericArguments(); + + Assert.Equal("M", method11Params[0].Name); + Assert.Equal("N", method11Params[1].Name); + Assert.Equal("A", method12Params[0].Name); + Assert.Equal("F", method12Params[4].Name); + Assert.Equal("T", method13Params[0].Name); + Assert.Equal("X", method21Params[0].Name); + Assert.Equal("Z", method21Params[2].Name); + } + } } // Test Types diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeTypeBuilder.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeTypeBuilder.Mono.cs index 469f9ef..8f4729a 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeTypeBuilder.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeTypeBuilder.Mono.cs @@ -1357,24 +1357,6 @@ namespace System.Reflection.Emit } } - [RequiresDynamicCode("The code for an array of the specified type might not be available.")] - public override Type MakeArrayType() - { - return SymbolType.FormCompoundType("[]", this, 0)!; - } - - [RequiresDynamicCode("The code for an array of the specified type might not be available.")] - public override Type MakeArrayType(int rank) - { - string s = GetRankString(rank); - return SymbolType.FormCompoundType(s, this, 0)!; - } - - public override Type MakeByRefType() - { - return SymbolType.FormCompoundType("&", this, 0)!; - } - [RequiresDynamicCode("The native code for this instantiation might not be available at runtime.")] [RequiresUnreferencedCode("If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), trimming can't validate that the requirements of those annotations are met.")] public override Type MakeGenericType(params Type[] typeArguments) @@ -1398,11 +1380,6 @@ namespace System.Reflection.Emit return RuntimeAssemblyBuilder.MakeGenericType(this, copy); } - public override Type MakePointerType() - { - return SymbolType.FormCompoundType("*", this, 0)!; - } - public override RuntimeTypeHandle TypeHandle { get