Debug.Assert(typeBuilder._handle.Equals(typeDefinitionHandle));
WriteCustomAttributes(typeBuilder._customAttributes, typeDefinitionHandle);
+ if ((typeBuilder.Attributes & TypeAttributes.ExplicitLayout) != 0)
+ {
+ _metadataBuilder.AddTypeLayout(typeDefinitionHandle, (ushort)typeBuilder.PackingSize, (uint)typeBuilder.Size);
+ }
+
+ if (typeBuilder._interfaces != null)
+ {
+ foreach(Type iface in typeBuilder._interfaces)
+ {
+ _metadataBuilder.AddInterfaceImplementation(typeDefinitionHandle, GetTypeHandle(iface));
+ // TODO: need to add interface mapping between interface method and implemented method
+ }
+ }
+
+ if (typeBuilder.DeclaringType != null)
+ {
+ _metadataBuilder.AddNestedType(typeDefinitionHandle, (TypeDefinitionHandle)GetTypeHandle(typeBuilder.DeclaringType));
+ }
+
foreach (MethodBuilderImpl method in typeBuilder._methodDefinitions)
{
MethodDefinitionHandle methodHandle = AddMethodDefinition(method, method.GetMethodSignatureBlob(), _nextParameterRowId);
return GetTypeReference(type);
}
+ internal TypeBuilder DefineNestedType(string name, TypeAttributes attr, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type? parent,
+ Type[]? interfaces, PackingSize packingSize, int typesize, TypeBuilderImpl? enclosingType)
+ {
+ TypeDefinitionHandle typeHandle = MetadataTokens.TypeDefinitionHandle(++_nextTypeDefRowId);
+ TypeBuilderImpl _type = new TypeBuilderImpl(name, attr, parent, this, typeHandle, interfaces, packingSize, typesize, enclosingType);
+ _typeDefinitions.Add(_type);
+ return _type;
+ }
[RequiresAssemblyFiles("Returns <Unknown> for modules with no file path")]
public override string Name => "<In Memory Module>";
protected override FieldBuilder DefineInitializedDataCore(string name, byte[] data, FieldAttributes attributes) => throw new NotImplementedException();
[RequiresUnreferencedCode("P/Invoke marshalling may dynamically access members that could be trimmed.")]
protected override MethodBuilder DefinePInvokeMethodCore(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, Type? returnType, Type[]? parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) => throw new NotImplementedException();
- protected override TypeBuilder DefineTypeCore(string name, TypeAttributes attr, [DynamicallyAccessedMembers((DynamicallyAccessedMemberTypes)(-1))] Type? parent, Type[]? interfaces, PackingSize packingSize, int typesize)
+ protected override TypeBuilder DefineTypeCore(string name, TypeAttributes attr,
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type? parent, Type[]? interfaces, PackingSize packingSize, int typesize)
{
TypeDefinitionHandle typeHandle = MetadataTokens.TypeDefinitionHandle(++_nextTypeDefRowId);
- TypeBuilderImpl _type = new TypeBuilderImpl(name, attr, parent, this, typeHandle, packingSize, typesize);
+ TypeBuilderImpl _type = new TypeBuilderImpl(name, attr, parent, this, typeHandle, interfaces, packingSize, typesize, null);
_typeDefinitions.Add(_type);
return _type;
}
private readonly string? _namespace;
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
private Type? _typeParent;
+ private readonly TypeBuilderImpl? _declaringType;
private TypeAttributes _attributes;
private PackingSize _packingSize;
private int _typeSize;
internal readonly TypeDefinitionHandle _handle;
internal readonly List<MethodBuilderImpl> _methodDefinitions = new();
internal readonly List<FieldBuilderImpl> _fieldDefinitions = new();
+ internal List<Type>? _interfaces;
internal List<CustomAttributeWrapper>? _customAttributes;
internal TypeBuilderImpl(string fullName, TypeAttributes typeAttributes,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type? parent, ModuleBuilderImpl module,
- TypeDefinitionHandle handle, PackingSize packingSize, int typeSize)
+ TypeDefinitionHandle handle, Type[]? interfaces, PackingSize packingSize, int typeSize, TypeBuilderImpl? enclosingType)
{
_name = fullName;
_module = module;
_typeSize = typeSize;
SetParent(parent);
_handle = handle;
+ _declaringType = enclosingType;
// Extract namespace from fullName
int idx = _name.LastIndexOf('.');
_namespace = _name[..idx];
_name = _name[(idx + 1)..];
}
+
+ if (interfaces != null)
+ {
+ _interfaces = new List<Type>();
+ for (int i = 0; i < interfaces.Length; i++)
+ {
+ Type @interface = interfaces[i];
+ // cannot contain null in the interface list
+ ArgumentNullException.ThrowIfNull(@interface, nameof(interfaces));
+ _interfaces.Add(@interface);
+ }
+ }
}
internal ModuleBuilderImpl GetModuleBuilder() => _module;
protected override PackingSize PackingSizeCore => _packingSize;
protected override int SizeCore => _typeSize;
- protected override void AddInterfaceImplementationCore([DynamicallyAccessedMembers((DynamicallyAccessedMemberTypes)(-1))] Type interfaceType) => throw new NotImplementedException();
+ protected override void AddInterfaceImplementationCore([DynamicallyAccessedMembers((DynamicallyAccessedMemberTypes.All))] Type interfaceType)
+ {
+ _interfaces ??= new List<Type>();
+ _interfaces.Add(interfaceType);
+ }
[return: DynamicallyAccessedMembers((DynamicallyAccessedMemberTypes)(-1))]
protected override TypeInfo CreateTypeInfoCore() => throw new NotImplementedException();
protected override ConstructorBuilder DefineConstructorCore(MethodAttributes attributes, CallingConventions callingConvention, Type[]? parameterTypes, Type[][]? requiredCustomModifiers, Type[][]? optionalCustomModifiers) => throw new NotImplementedException();
}
protected override void DefineMethodOverrideCore(MethodInfo methodInfoBody, MethodInfo methodInfoDeclaration) => throw new NotImplementedException();
- protected override TypeBuilder DefineNestedTypeCore(string name, TypeAttributes attr, [DynamicallyAccessedMembers((DynamicallyAccessedMemberTypes)(-1))] Type? parent, Type[]? interfaces, Emit.PackingSize packSize, int typeSize) => throw new NotImplementedException();
+ protected override TypeBuilder DefineNestedTypeCore(string name, TypeAttributes attr,
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type? parent, Type[]? interfaces, PackingSize packSize, int typeSize)
+ {
+ return _module.DefineNestedType(name, attr, parent, interfaces, packSize, typeSize, this);
+ }
+
[RequiresUnreferencedCode("P/Invoke marshalling may dynamically access members that could be trimmed.")]
protected override MethodBuilder DefinePInvokeMethodCore(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, Type? returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers, Type[]? parameterTypes, Type[][]? parameterTypeRequiredCustomModifiers, Type[][]? parameterTypeOptionalCustomModifiers, CallingConvention nativeCallConv, CharSet nativeCharSet) => throw new NotImplementedException();
protected override PropertyBuilder DefinePropertyCore(string name, PropertyAttributes attributes, CallingConventions callingConvention, Type returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers, Type[]? parameterTypes, Type[][]? parameterTypeRequiredCustomModifiers, Type[][]? parameterTypeOptionalCustomModifiers) => throw new NotImplementedException();
}
}
public override string Name => _name;
+ public override Type? DeclaringType => _declaringType;
+ public override Type? ReflectedType => _declaringType;
public override bool IsDefined(Type attributeType, bool inherit) => throw new NotImplementedException();
public override object[] GetCustomAttributes(bool inherit) => throw new NotImplementedException();
public override object[] GetCustomAttributes(Type attributeType, bool inherit) => throw new NotImplementedException();
public override Type? GetInterface(string name, bool ignoreCase) => throw new NotSupportedException();
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
- public override Type[] GetInterfaces() => throw new NotSupportedException();
+ public override Type[] GetInterfaces() => _interfaces == null ? EmptyTypes : _interfaces.ToArray();
+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) => throw new NotSupportedException();
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
// 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;
Assert.Equal("System.Void", method.ReturnType.FullName);
}
}
+
+ [Fact]
+ public void AddInterfaceImplementationTest()
+ {
+ 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, null, new Type[] { typeof(IOneMethod)});
+ tb.AddInterfaceImplementation(typeof(INoMethod));
+ tb.DefineNestedType("NestedType", TypeAttributes.Interface | TypeAttributes.Abstract);
+ saveMethod.Invoke(assemblyBuilder, new object[] { file.Path });
+
+ Assembly assemblyFromDisk = AssemblyTools.LoadAssemblyFromPath(file.Path);
+ Type testType = assemblyFromDisk.Modules.First().GetTypes()[0];
+ Type[] interfaces = testType.GetInterfaces();
+
+ Assert.Equal("TestInterface", testType.Name);
+ Assert.Equal(2, interfaces.Length);
+
+ Type iOneMethod = testType.GetInterface("IOneMethod");
+ Type iNoMethod = testType.GetInterface("INoMethod");
+ Type[] nt = testType.GetNestedTypes();
+ Assert.Equal(1, iOneMethod.GetMethods().Length);
+ Assert.Empty(iNoMethod.GetMethods());
+ Assert.NotNull(testType.GetNestedType("NestedType", BindingFlags.NonPublic));
+ }
+ }
}
// Test Types