Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add implementations for MakePointerType(), MakeArrayType() for GenericTypeParameterBuilder #97350

Merged
merged 15 commits into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public override object Invoke(object? obj, BindingFlags invokeAttr, Binder? bind
public override CallingConventions CallingConvention => _ctor.CallingConvention;
public override Type[] GetGenericArguments() { return _ctor.GetGenericArguments(); }
public override bool IsGenericMethodDefinition => false;
public override bool ContainsGenericParameters => false;
public override bool ContainsGenericParameters => _type.ContainsGenericParameters;

public override bool IsGenericMethod => false;
#endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,26 @@ public override bool ContainsGenericParameters
{
get
{
if (_method.ContainsGenericParameters)
if (_method.ContainsGenericParameters || _type.ContainsGenericParameters)
{
return true;
if (!_method.IsGenericMethodDefinition)
throw new NotSupportedException();
}

return _method.ContainsGenericParameters;
if (!IsGenericMethod)
{
return false;
}
Comment on lines +87 to +90
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This defers to _method.IsGenericMethod, which seems close to _method.ContainsGenericParameters. Does the latter inform the former?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, _method.ContainsGenericParameters could be true when method is not generic, but the containing type has any open generic parameter.


Type[] args = GetGenericArguments();
for (int i = 0; i < args.Length; i++)
{
if (args[i].ContainsGenericParameters)
{
return true;
}
}

return false;
}
}
[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.")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,18 +271,30 @@ public override Type MakeByRefType()
return FormCompoundType(_format + "&", _baseType, 0)!;
}

[RequiresDynamicCode("The code for an array of the specified type might not be available.")]
steveharter marked this conversation as resolved.
Show resolved Hide resolved
public override Type MakeArrayType()
{
return FormCompoundType(_format + "[]", _baseType, 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);
string s = FormatRank(rank);
steveharter marked this conversation as resolved.
Show resolved Hide resolved
SymbolType? st = FormCompoundType(_format + s, _baseType, 0) as SymbolType;
return st!;
}

internal static string FormatRank(int rank)
{
if (rank <= 0)
{
throw new IndexOutOfRangeException();
}

return rank == 1 ? "[*]" : "[" + new string(',', rank - 1) + "]";
}

public override int GetArrayRank()
{
if (!IsArray)
Expand Down Expand Up @@ -440,18 +452,25 @@ public override Type GetNestedType(string name, BindingFlags bindingAttr)
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}

[DynamicallyAccessedMembers(GetAllMembers)]
[DynamicallyAccessedMembers(GetAllMembersInternal)]
public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr)
{
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}

[DynamicallyAccessedMembers(GetAllMembers)]
[DynamicallyAccessedMembers(GetAllMembersInternal)]
steveharter marked this conversation as resolved.
Show resolved Hide resolved
public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
{
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}

private const DynamicallyAccessedMemberTypes GetAllMembersInternal = DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields |
DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods |
DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents |
DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties |
DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors |
DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes;

public override InterfaceMapping GetInterfaceMap([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] Type interfaceType)
{
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
Expand Down
12 changes: 12 additions & 0 deletions src/libraries/System.Reflection.Emit/src/Resources/Strings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -288,4 +288,16 @@
<data name="InvalidOperation_TokenNotPopulated" xml:space="preserve">
<value>MetadataToken for the member is not generated until the assembly saved.</value>
</data>
<data name="Argument_BadSigFormat" xml:space="preserve">
steveharter marked this conversation as resolved.
Show resolved Hide resolved
<value>Incorrect signature format.</value>
</data>
<data name="Argument_HasToBeArrayClass" xml:space="preserve">
<value>Must be an array type.</value>
</data>
<data name="NotSupported_NonReflectedType" xml:space="preserve">
<value>Not supported in a non-reflected type.</value>
</data>
<data name="NotSupported_SymbolMethod" xml:space="preserve">
<value>Not supported in an array method of a type definition that is not complete.</value>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@

<ItemGroup>
<Compile Include="$(CoreLibSharedDir)System\Reflection\Emit\MethodBuilderInstantiation.cs" Link="System\Reflection\Emit\MethodBuilderInstantiation.cs" />
<Compile Include="$(CoreLibSharedDir)System\Reflection\Emit\SymbolType.cs" Link="System\Reflection\Emit\SymbolType.cs" />
<Compile Include="$(CoreLibSharedDir)System\Reflection\Emit\TypeNameBuilder.cs" Link="System\Reflection\Emit\TypeNameBuilder.cs" />
<Compile Include="System\Reflection\Emit\ArrayMethod.cs" />
<Compile Include="System\Reflection\Emit\ConstructorBuilderImpl.cs" />
<Compile Include="System\Reflection\Emit\CustomAttributeWrapper.cs" />
<Compile Include="System\Reflection\Emit\AssemblyBuilderImpl.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Globalization;

namespace System.Reflection.Emit
{
internal sealed class ArrayMethod : MethodInfo
{
#region Private Data Members
private readonly ModuleBuilder _module;
private readonly Type _containingType;
private readonly string _name;
private readonly CallingConventions _callingConvention;
private readonly Type _returnType;
private readonly Type[] _parameterTypes;
#endregion

#region Constructor
// This is a kind of MethodInfo to represent methods for array type of unbaked type
internal ArrayMethod(ModuleBuilder module, Type arrayClass, string methodName,
CallingConventions callingConvention, Type? returnType, Type[]? parameterTypes)
{
_returnType = returnType ?? typeof(void);
if (parameterTypes != null)
{
_parameterTypes = new Type[parameterTypes.Length];
for (int i = 0; i < parameterTypes.Length; i++)
{
ArgumentNullException.ThrowIfNull(_parameterTypes[i] = parameterTypes[i], nameof(parameterTypes));
buyaa-n marked this conversation as resolved.
Show resolved Hide resolved
}
}
else
{
_parameterTypes = Type.EmptyTypes;
}

_module = module;
_containingType = arrayClass;
_name = methodName;
_callingConvention = callingConvention;
}
#endregion

#region Internal Members
internal Type[] ParameterTypes => _parameterTypes;
#endregion

#region MemberInfo Overrides
public override Module Module => _module;

public override Type? ReflectedType => _containingType;

public override string Name => _name;

public override Type? DeclaringType => _containingType;
#endregion

#region MethodBase Overrides
public override ParameterInfo[] GetParameters() => throw new NotSupportedException(SR.NotSupported_SymbolMethod);

public override MethodImplAttributes GetMethodImplementationFlags() => throw new NotSupportedException(SR.NotSupported_SymbolMethod);

public override MethodAttributes Attributes => MethodAttributes.PrivateScope;

public override CallingConventions CallingConvention => _callingConvention;

public override RuntimeMethodHandle MethodHandle => throw new NotSupportedException(SR.NotSupported_SymbolMethod);
#endregion

#region MethodInfo Overrides
public override Type ReturnType => _returnType;

public override ICustomAttributeProvider ReturnTypeCustomAttributes => throw new NotSupportedException(SR.NotSupported_SymbolMethod);

public override object Invoke(object? obj, BindingFlags invokeAttr, Binder? binder, object?[]? parameters, CultureInfo? culture)
=> throw new NotSupportedException(SR.NotSupported_SymbolMethod);

public override MethodInfo GetBaseDefinition() => this;
#endregion

#region ICustomAttributeProvider Implementation
public override object[] GetCustomAttributes(bool inherit) => throw new NotSupportedException(SR.NotSupported_SymbolMethod);

public override object[] GetCustomAttributes(Type attributeType, bool inherit) => throw new NotSupportedException(SR.NotSupported_SymbolMethod);

public override bool IsDefined(Type attributeType, bool inherit) => throw new NotSupportedException(SR.NotSupported_SymbolMethod);
#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ protected override FieldBuilder DefineLiteralCore(string literalName, object? li
{
FieldBuilder fieldBuilder = _typeBuilder.DefineField(
literalName,
_typeBuilder,
this,
FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal);
fieldBuilder.SetConstant(literalValue);
return fieldBuilder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,14 @@ internal static void ValidateDefaultValueType(object? defaultValue, Type destina
{
underlyingType = enumBldr.GetEnumUnderlyingType();

if (sourceType != enumBldr._typeBuilder.UnderlyingSystemType && sourceType != underlyingType)
if (sourceType != enumBldr._typeBuilder.UnderlyingSystemType &&
sourceType != underlyingType &&
// If the source type is an enum, should not throw when the underlying types match
sourceType.IsEnum &&
sourceType.GetEnumUnderlyingType() != underlyingType)
{
throw new ArgumentException(SR.Argument_ConstantDoesntMatch);
}
}
else if (destinationType is TypeBuilderImpl typeBldr)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public override Type[] GetGenericParameterConstraints() =>
public override bool IsGenericType => false;
public override bool IsGenericParameter => true;
public override bool IsConstructedGenericType => false;
public override bool ContainsGenericParameters => _type.ContainsGenericParameters;
public override bool ContainsGenericParameters => false;
steveharter marked this conversation as resolved.
Show resolved Hide resolved
public override MethodBase? DeclaringMethod => _type.DeclaringMethod;
public override Type? BaseType => _parent;
public override RuntimeTypeHandle TypeHandle => throw new NotSupportedException();
Expand Down Expand Up @@ -137,5 +137,19 @@ public override Type[] GetGenericParameterConstraints() =>
public override MemberInfo[] GetMembers(BindingFlags bindingAttr) => throw new NotSupportedException();
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
public override object InvokeMember(string name, BindingFlags invokeAttr, Binder? binder, object? target, object?[]? args, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParameters) => throw new NotSupportedException();

public override Type MakePointerType() =>
SymbolType.FormCompoundType("*", this, 0)!;

public override Type MakeByRefType() =>
SymbolType.FormCompoundType("&", this, 0)!;

[RequiresDynamicCode("The code for an array of the specified type might not be available.")]
public override Type MakeArrayType() =>
SymbolType.FormCompoundType("[]", this, 0)!;

[RequiresDynamicCode("The code for an array of the specified type might not be available.")]
public override Type MakeArrayType(int rank) =>
SymbolType.FormCompoundType(SymbolType.FormatRank(rank), this, 0)!;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ public override void Emit(OpCode opcode, Type cls)
ArgumentNullException.ThrowIfNull(cls);

EmitOpcode(opcode);
WriteOrReserveToken(_moduleBuilder.GetTypeHandle(cls), cls);
WriteOrReserveToken(_moduleBuilder.GetTypeHandleForIL(cls), cls);
buyaa-n marked this conversation as resolved.
Show resolved Hide resolved
}

public override void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[]? optionalParameterTypes)
Expand Down Expand Up @@ -616,6 +616,10 @@ private static int GetStackChange(OpCode opcode, MethodInfo methodInfo, Type[]?
{
stackChange -= builder.ParameterCount;
}
else if (methodInfo is ArrayMethod sm)
{
stackChange -= sm.ParameterTypes.Length;
}
else
{
stackChange -= methodInfo.GetParameters().Length;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ protected override void SetSignatureCore(Type? returnType, Type[]? returnTypeReq
public override CallingConventions CallingConvention => _callingConventions;
public override Type? DeclaringType => _declaringType._isHiddenGlobalType ? null : _declaringType;
public override Module Module => _module;
public override bool ContainsGenericParameters => throw new NotSupportedException();
public override bool ContainsGenericParameters => _typeParameters != null;
public override bool IsGenericMethod => _typeParameters != null;
public override bool IsGenericMethodDefinition => _typeParameters != null;
public override bool IsSecurityCritical => true;
Expand Down
Loading
Loading